是否有任何库或算法来沙姆西(贾拉利)转换成公历日期在Java中? [英] Is there any library or algorithm to convert Shamsi(Jalali) to Gregorian date in Java?

查看:240
本文介绍了是否有任何库或算法来沙姆西(贾拉利)转换成公历日期在Java中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有图书馆或算法来沙姆西(贾拉利)转换成公历日期在Java中?


解决方案

 进口java.util.Calendar中;
进口java.util.Date;
进口java.util.GregorianCalendar中;
进口java.util.Locale中;
进口java.util.TimeZone中;公共类JalaliCalendar扩展日历{
    公共静态INT gregorianDaysInMonth [] = {31,28,31,30,31,30,31,
            31,30,31,30,31};
    公共静态INT jalaliDaysInMonth [] = {31,31,31,31,31,31,30,30,
            30,30,30,29};    公众最终静态INT FARVARDIN = 0;
    公众最终静态INT ORDIBEHESHT = 1;
    公众最终静态INT KHORDAD = 2;
    公众最终静态INT TIR = 3;
    公众最终静态INT MORDAD = 4;
    公众最终静态INT SHAHRIVAR = 5;
    公众最终静态INT MEHR = 6;
    公众最终静态INT ABAN = 7;
    公众最终静态INT AZAR = 8;
    公众最终静态INT DEY = 9;
    公众最终静态INT巴曼= 10;
    公众最终静态INT ESFAND = 11;    私有静态时区的timeZone = TimeZone.getDefault();
    私有静态布尔isTimeSeted = FALSE;    私有静态最终诠释ONE_SECOND = 1000;
    私有静态最终诠释ONE_MINUTE = 60 * ONE_SECOND;
    私有静态最终诠释ONE_HOUR = 60 * ONE_MINUTE;
    私有静态最后长ONE_DAY = 24 * ONE_HOUR;
    静态最终诠释BCE = 0;
    静态最终诠释CE = 1;
    公共静态最终诠释AD = 1;
    私人GregorianCalendar的CAL;    静态最终诠释MIN_VALUES [] = {BCE,1,FARVARDIN,1,0,1,1,星期六,
            1,AM,0,0,0,0,0,-13 * ONE_HOUR,0};    静态最终诠释LEAST_MAX_VALUES [] = {CE,292269054,ESFAND,52,4,28,
            365,周五,4,PM,11,23,59,59,999,14 * ONE_HOUR,
            20 * ONE_MINUTE};    静态最终诠释MAX_VALUES [] = {CE,292278994,ESFAND,53,6,31,366,
            星期五,6,PM,11,23,59,59,999,14 * ONE_HOUR,2 * ONE_HOUR};    公共JalaliCalendar(){
        这个(TimeZone.getDefault(),Locale.getDefault());
    }    公共JalaliCalendar(时区区域){
        这个(区,Locale.getDefault());
    }    公共JalaliCalendar(区域设置aLocale){
        这个(TimeZone.getDefault(),aLocale);
    }    公共JalaliCalendar(TimeZone的区域,区域设置aLocale){        超(区,aLocale);
        的timeZone =区;
        台历挂历= Calendar.getInstance(区,aLocale);        年月日年月日=新的年月日(calendar.get(YEAR)
                calendar.get(月),calendar.get(DATE));
        年月日= gregorianToJalali(年月日);
        集(yearMonthDate.getYear(),yearMonthDate.getMonth()
                yearMonthDate.getDate());
        完成();    }    公开日期getGregorianDate(字符串jalaliDate){
        的String [] = ARR jalaliDate.split(/);        年月日贾拉利=新的年月日(的Integer.parseInt(ARR [0]),
                的Integer.parseInt(改编[1]) - 1,的Integer.parseInt(改编[2]));        年月日gDate = jalaliToGregorian(贾拉利);        日历CAL = Calendar.getInstance();
        cal.clear();
        cal.set(gDate.getYear(),gDate.getMonth(),gDate.getDate());        日期DT = cal.getTime();        返回DT;
    }    公共字符串getJalaliDate(日期gDate){        日历克卡= Calendar.getInstance();        gCal.clear();        gCal.setTime(gDate);
        日期DT = gCal.getTime();
        INT myYear = gCal.get(Calendar.YEAR);
        INT myMonth = gCal.get(的Calendar.MONTH);
        INT myDay = gCal.get(Calendar.DAY_OF_MONTH);
        年月日gMyDate =新的年月日(myYear,myMonth,myDay);        年月日jDate = gregorianToJalali(gMyDate);        串贾拉利= jDate.year +/+(jDate.month + 1)+/+ jDate.date;        返回贾拉利;
    }    公共JalaliCalendar(INT年,月整型,诠释请将dayOfMonth){
        这(年,月,请将dayOfMonth,0,0,0,0);
    }    公共JalaliCalendar(INT年,月整型,诠释请将dayOfMonth,INT HOUROFDAY,
            分整型){
        这(年,月,请将dayOfMonth,HOUROFDAY,分钟,0,0);
    }    公共JalaliCalendar(INT年,月整型,诠释请将dayOfMonth,INT HOUROFDAY,
            INT分钟,INT秒){
        这(年,月,请将dayOfMonth,HOUROFDAY,分,秒,0);
    }    JalaliCalendar(INT年,月整型,诠释请将dayOfMonth,INT HOUROFDAY,
            INT分钟,秒整型,诠释米利斯){
        超();        this.set(年,年);
        this.set(月,月);
        this.set(DAY_OF_MONTH,请将dayOfMonth);        如果(HOUROFDAY> = 12安培;&安培; HOUROFDAY< = 23){            this.set(AM_PM,PM);
            this.set(小时,HOUROFDAY - 12);
        }其他{
            this.set(HOUR,HOUROFDAY);
            this.set(AM_PM,AM);
        }        this.set(HOUR_OF_DAY,HOUROFDAY);
        this.set(分,分);
        this.set(第二,秒);        this.set(毫秒米利斯);        年月日年月日= jalaliToGregorian(新年月日(
                字段[1],字段[2],字段[5]));
        CAL =新的GregorianCalendar(yearMonthDate.getYear()
                yearMonthDate.getMonth(),yearMonthDate.getDate(),HOUROFDAY,
                分,秒);
        时间= cal.getTimeInMillis();        isTimeSeted = TRUE;
    }    公共静态年月日gregorianToJalali(年月日阳历){        如果(gregorian.getMonth()> 11 || gregorian.getMonth()&下; -11){
            抛出新抛出:IllegalArgumentException();
        }
        INT jalaliYear;
        INT jalaliMonth;
        INT jalaliDay;        INT gregorianDayNo,jalaliDayNo;
        INT jalaliNP;
        INT I;        gregorian.setYear(gregorian.getYear() - 1600);
        gregorian.setDate(gregorian.getDate() - 1);        gregorianDayNo = 365 * gregorian.getYear()
                +(int)的Math.floor((gregorian.getYear()+ 3)/ 4)
                 - (INT)Math.floor((gregorian.getYear()+ 99)/ 100)
                +(INT)Math.floor((gregorian.getYear()+ 399)/ 400);
        对于(i = 0; I< gregorian.getMonth(); ++ I){
            gregorianDayNo + = gregorianDaysInMonth [I]
        }        如果(gregorian.getMonth()大于1
                &功放;&安培; ((gregorian.getYear()%4 == 0安培;&安培;!gregorian.getYear()%100 = 0)||(阳历
                        .getYear()%400 == 0))){
            ++ gregorianDayNo;
        }        gregorianDayNo + = gregorian.getDate();        jalaliDayNo = gregorianDayNo - 79;        jalaliNP =(INT)Math.floor(jalaliDayNo / 12053);
        jalaliDayNo = jalaliDayNo%12053;        jalaliYear = 979 + 33 * jalaliNP + 4 *(INT)(jalaliDayNo / 1461);
        jalaliDayNo = jalaliDayNo%1461;        如果(jalaliDayNo> = 366){
            jalaliYear + =(INT)Math.floor((jalaliDayNo - 1)/ 365);
            jalaliDayNo =(jalaliDayNo - 1)%365;
        }        对于(I = 0; I&11选自放大器;&放大器; jalaliDayNo&GT = jalaliDaysInMonth [I] ++ⅰ){
            jalaliDayNo - = jalaliDaysInMonth [I];
        }
        jalaliMonth = I;
        jalaliDay = jalaliDayNo + 1;        返回新的年月日(jalaliYear,jalaliMonth,jalaliDay);
    }    公共静态年月日jalaliToGregorian(年月日贾拉利){
        如果(jalali.getMonth()> 11 || jalali.getMonth()&下; -11){
            抛出新抛出:IllegalArgumentException();
        }        INT gregorianYear;
        INT gregorianMonth;
        INT gregorianDay;        INT gregorianDayNo,jalaliDayNo;
        INT飞跃;        INT I;
        jalali.setYear(jalali.getYear() - 979);
        jalali.setDate(jalali.getDate() - 1);        jalaliDayNo = 365 * jalali.getYear()+(INT)(jalali.getYear()/ 33)
                * 8 +(int)的Math.floor(((jalali.getYear()%33)+ 3)/ 4);
        对于(i = 0; I< jalali.getMonth(); ++ I){
            jalaliDayNo + = jalaliDaysInMonth [I]
        }        jalaliDayNo + = jalali.getDate();        gregorianDayNo = jalaliDayNo + 79;        gregorianYear = 1600 + 400 *(INT)Math.floor(gregorianDayNo / 146097); / *
                                                                                 * 146097
                                                                                 * =
                                                                                 * 365
                                                                                 * *
                                                                                 * 400
                                                                                 * +
                                                                                 * 400
                                                                                 * /
                                                                                 * 4
                                                                                 * -
                                                                                 * 400
                                                                                 * /
                                                                                 * 100
                                                                                 * +
                                                                                 * 400
                                                                                 * /
                                                                                 * 400
                                                                                 * /
        gregorianDayNo = gregorianDayNo%146097;        飞跃= 1;
        如果(gregorianDayNo> = 36525)/ * 36525 = 365 * 100 + 100/4 * / {
            gregorianDayNo--;
            gregorianYear + = 100 *(INT)Math.floor(gregorianDayNo / 36524); / *
                                                                             * 36524
                                                                             * =
                                                                             * 365
                                                                             * *
                                                                             * 100
                                                                             * +
                                                                             * 100
                                                                             * /
                                                                             * 4
                                                                             * -
                                                                             * 100
                                                                             * /
                                                                             * 100
                                                                             * /
            gregorianDayNo = gregorianDayNo%36524;            如果(gregorianDayNo> = 365){
                gregorianDayNo ++;
            }其他{
                飞跃= 0;
            }
        }        gregorianYear + = 4 *(INT)Math.floor(gregorianDayNo / 1461); / *
                                                                     * 1461 =
                                                                     * 365 * 4 +
                                                                     * 4/4
                                                                     * /
        gregorianDayNo = gregorianDayNo%1461;        如果(gregorianDayNo> = 366){
            飞跃= 0;            gregorianDayNo--;
            gregorianYear + =(INT)Math.floor(gregorianDayNo / 365);
            gregorianDayNo = gregorianDayNo%365;
        }        对于(I = 0; gregorianDayNo&GT = gregorianDaysInMonth [I]
                +((我== 1安培;&安培;飞跃== 1)I:0);我++){
            gregorianDayNo - = gregorianDaysInMonth [I]
                    +((我== 1安培;&安培;飞跃== 1)I:0);
        }
        gregorianMonth = I;
        gregorianDay = gregorianDayNo + 1;        返回新的年月日(gregorianYear,gregorianMonth,gregorianDay);    }    公共静态INT WEEKOFYEAR(INT DAYOFYEAR,INT年){
        开关(一周中的某天(JalaliCalendar.jalaliToGregorian(新年月日(
                年,0,1)))){
        案例2:
            DAYOFYEAR ++;
            打破;
        案例3:
            DAYOFYEAR + = 2;
            打破;
        情况4:
            DAYOFYEAR + = 3;
            打破;
        情况5:
            DAYOFYEAR + = 4;
            打破;
        情况6:
            DAYOFYEAR + = 5;
            打破;
        案例7:
            dayOfYear--;
            打破;
        }
        ;
        DAYOFYEAR =(INT)Math.floor(DAYOFYEAR / 7);
        返回DAYOFYEAR + 1;
    }    公共静态INT一周中的某天(年月日年月日){        日历CAL =新的GregorianCalendar(yearMonthDate.getYear()
                yearMonthDate.getMonth(),yearMonthDate.getDate());
        返回cal.get(DAY_OF_WEEK);    }    公共静态布尔isLeepYear(INT年){
        //算法从www.wikipedia.com
        如果((年33%== 1 ||年33%5 = = ||年33%9 ==
                ||年33%13 = = ||年33%17 = = ||年33%22 ==
                ||年33%26 = = ||年33%30 = =)){
            返回true;
        }其他
            返回false;
    }    @覆盖
    保护无效computeTime(){        如果(isTimeSet&安培;!&安培;!isTimeSeted){
            日历CAL = GregorianCalendar.getInstance(的timeZone);
            如果(!使用isset(HOUR_OF_DAY)){
                super.set(HOUR_OF_DAY,cal.get(HOUR_OF_DAY));
            }
            如果(!使用isset(HOUR)){
                super.set(HOUR,cal.get(HOUR));
            }
            如果(!使用isset(分)){
                super.set(分,cal.get(分));
            }
            如果(!使用isset(秒)){
                super.set(SECOND,cal.get(秒));
            }
            如果(!使用isset(微差)){
                super.set(毫秒cal.get(微差));
            }
            如果(!使用isset(ZONE_OFFSET)){
                super.set(ZONE_OFFSET,cal.get(ZONE_OFFSET));
            }
            如果(!使用isset(DST_OFFSET)){
                super.set(DST_OFFSET,cal.get(DST_OFFSET));
            }
            如果(!使用isset(AM_PM)){
                super.set(AM_PM,cal.get(AM_PM));
            }            如果(internalGet(HOUR_OF_DAY)> = 12
                    &功放;&安培; internalGet(HOUR_OF_DAY)LT = 23){
                super.set(AM_PM,PM);
                super.set(小时,internalGet(HOUR_OF_DAY) - 12);
            }其他{
                super.set(小时,internalGet(HOUR_OF_DAY));
                super.set(AM_PM,AM);
            }            年月日年月日= jalaliToGregorian(新年月日(
                    internalGet(YEAR),internalGet(月),
                    internalGet(DAY_OF_MONTH)));
            cal.set(yearMonthDate.getYear(),yearMonthDate.getMonth(),
                    yearMonthDate.getDate(),internalGet(HOUR_OF_DAY),
                    internalGet(分),internalGet(秒));
            时间= cal.getTimeInMillis();        }否则如果(isTimeSet&安培;!&安培; isTimeSeted){
            如果(internalGet(HOUR_OF_DAY)> = 12
                    &功放;&安培; internalGet(HOUR_OF_DAY)LT = 23){
                super.set(AM_PM,PM);
                super.set(小时,internalGet(HOUR_OF_DAY) - 12);
            }其他{
                super.set(小时,internalGet(HOUR_OF_DAY));
                super.set(AM_PM,AM);
            }
            CAL =新的GregorianCalendar();
            super.set(ZONE_OFFSET,timeZone.getRawOffset());
            super.set(DST_OFFSET,timeZone.getDSTSavings());
            年月日年月日= jalaliToGregorian(新年月日(
                    internalGet(YEAR),internalGet(月),
                    internalGet(DAY_OF_MONTH)));
            cal.set(yearMonthDate.getYear(),yearMonthDate.getMonth(),
                    yearMonthDate.getDate(),internalGet(HOUR_OF_DAY),
                    internalGet(分),internalGet(秒));
            时间= cal.getTimeInMillis();
        }
    }    公共无效集(INT领域,int值){
        开关(场){
        案例日期:{
            super.set(场,0);
            增加(场,值);
            打破;
        }
        案例MONTH:{
            如果(价值> 11){
                super.set(场,11);
                增加(场,值 - 11);
            }否则如果(值小于0){
                super.set(场,0);
                增加(场,值);
            }其他{
                super.set(场,值);
            }
            打破;
        }
        案例DAY_OF_YEAR:{
            如果(使用isset(YEAR)及和放大器;使用isset(月)及和放大器;使用isset(DAY_OF_MONTH)){
                super.set(YEAR,internalGet(年));
                super.set(月,0);
                super.set(DATE,0);
                增加(场,值);
            }其他{
                super.set(场,值);
            }
            打破;
        }
        案例WEEK_OF_YEAR:{
            如果(使用isset(YEAR)及和放大器;使用isset(月)及和放大器;使用isset(DAY_OF_MONTH)){
                增加(场,价值 - 让(WEEK_OF_YEAR));
            }其他{
                super.set(场,值);
            }
            打破;
        }
        案例WEEK_OF_MONTH:{
            如果(使用isset(YEAR)及和放大器;使用isset(月)及和放大器;使用isset(DAY_OF_MONTH)){
                增加(场,价值 - 让(WEEK_OF_MONTH));
            }其他{
                super.set(场,值);
            }
            打破;
        }
        案例DAY_OF_WEEK:{
            如果(使用isset(YEAR)及和放大器;使用isset(月)及和放大器;使用isset(DAY_OF_MONTH)){
                加(DAY_OF_WEEK,价值7% - 得到(DAY_OF_WEEK));
            }其他{
                super.set(场,值);
            }
            打破;
        }
        案例HOUR_OF_DAY:
        案例HOUR:
        案例MINUTE:
        第二案:
        案例微差:
        案例ZONE_OFFSET:
        案例DST_OFFSET:{
            如果(使用isset(YEAR)及和放大器;使用isset(月)及和放大器;使用isset(DATE)及和放大器;使用isset(小时)
                    &功放;&安培;使用isset(HOUR_OF_DAY)及&放大器;使用isset(分钟)及和放大器;使用isset(第二次)
                    &功放;&安培;使用isset(微差)){
                CAL =新的GregorianCalendar();
                年月日年月日= jalaliToGregorian(新年月日(
                        internalGet(YEAR),internalGet(月),
                        internalGet(DATE)));
                cal.set(yearMonthDate.getYear(),yearMonthDate.getMonth(),
                        yearMonthDate.getDate(),internalGet(HOUR_OF_DAY),
                        internalGet(分),internalGet(秒));
                cal.set(场,值);
                年月日= gregorianToJalali(新年月日(
                        cal.get(YEAR),cal.get(月),cal.get(DATE)));
                super.set(YEAR,yearMonthDate.getYear());
                super.set(月,yearMonthDate.getMonth());
                super.set(DATE,yearMonthDate.getDate());
                super.set(HOUR_OF_DAY,cal.get(HOUR_OF_DAY));
                super.set(分,cal.get(分));
                super.set(SECOND,cal.get(秒));            }其他{
                super.set(场,值);
            }
            打破;
        }        默认:{
            super.set(场,值);
        }
        }
    }    @覆盖
    保护无效computeFields(){
        布尔TEMP = isTimeSet;
        如果(!areFieldsSet){
            setMinimalDaysInFirstWeek(1);
            setFirstDayOfWeek(7);            // DAY_OF_YEAR
            INT DAYOFYEAR = 0;
            INT索引= 0;            而(指数<领域[2]){
                DAYOFYEAR + = jalaliDaysInMonth [指数++];
            }
            DAYOFYEAR + =字段[5];
            super.set(DAY_OF_YEAR,DAYOFYEAR);
            // ***            // DAY_OF_WEEK
            super.set(DAY_OF_WEEK,
                    一周中的某天(jalaliToGregorian(新年月日(领域[1],
                            领域[2],字段[5]))));
            // ***            // DAY_OF_WEEK_IN_MONTH
            如果(0℃;字段[5]&放大器;&放大器;字段[5]所述; 8){
                super.set(DAY_OF_WEEK_IN_MONTH,1);
            }            如果(7所述;字段[5]&放大器;&放大器;字段[5]所述; 15){
                super.set(DAY_OF_WEEK_IN_MONTH,2);
            }            如果(14下;字段[5]&放大器;&放大器;字段[5]所述; 22){
                super.set(DAY_OF_WEEK_IN_MONTH,3);
            }            如果(21下;字段[5]&放大器;&放大器;字段[5]所述; 29){
                super.set(DAY_OF_WEEK_IN_MONTH,4);
            }            如果(28和;字段[5]&放大器;&放大器;字段[5]所述; 32){
                super.set(DAY_OF_WEEK_IN_MONTH,5);
            }
            // ***            // WEEK_OF_YEAR
            super.set(WEEK_OF_YEAR,WEEKOFYEAR(字段[6],字段[1]));
            // ***            // WEEK_OF_MONTH
            super.set(WEEK_OF_MONTH,WEEKOFYEAR(字段[6],字段[1])
                     - WEEKOFYEAR(字段[6] - 字段[5],字段[1])+ 1);
            //            isTimeSet =温度;
        }
    }    @覆盖
    公共无效添加(INT场,诠释金额){        如果(场== MONTH){
            量+ = GET(MONTH);
            加(年,金额/ 12);
            super.set(月,金额12%​​);
            如果(获取(DAY_OF_MONTH)GT; jalaliDaysInMonth [金额12%​​]){
                super.set(DAY_OF_MONTH,jalaliDaysInMonth [金额12%​​]);
                如果(获取(月)== 11安培;&安培; isLeepYear(获取(年))){
                    super.set(DAY_OF_MONTH,30);
                }
            }
            完成();        }否则如果(场== YEAR){            super.set(YEAR,得到(YEAR)+量);
            如果(获取(DAY_OF_MONTH)== 30安培;&安培;得到(月)== 11
                    &功放;&安培; !isLeepYear(获取(年))){
                super.set(DAY_OF_MONTH,29);
            }            完成();
        }其他{
            年月日年月日= jalaliToGregorian(新年月日(
                    得到(YEAR),拿到(月),获得(DATE)));
            日历GC =新的GregorianCalendar(yearMonthDate.getYear()
                    yearMonthDate.getMonth(),yearMonthDate.getDate(),
                    得到(HOUR_OF_DAY),拿到(分),获得(秒));
            gc.add(领域,金额);
            年月日= gregorianToJalali(新年月日(gc.get(YEAR)
                    gc.get(月),gc.get(DATE)));
            super.set(YEAR,yearMonthDate.getYear());
            super.set(月,yearMonthDate.getMonth());
            super.set(DATE,yearMonthDate.getDate());
            super.set(HOUR_OF_DAY,gc.get(HOUR_OF_DAY));
            super.set(分,gc.get(分));
            super.set(SECOND,gc.get(秒));
            完成();
        }    }    @覆盖
    公共无效卷(INT场,布尔值高达){
        辊(场,最多+1:-1);
    }    @覆盖
    公共无效卷(INT场,诠释金额){
        如果(金额== 0){
            返回;
        }        如果(场℃,||​​场> = ZONE_OFFSET){
            抛出新抛出:IllegalArgumentException();
        }        完成();        开关(场){
        案例AM_PM:{
            如果(数额%2!= 0){
                如果(internalGet(AM_PM)== AM){
                    域[AM_PM] = PM;
                }其他{
                    域[AM_PM] = AM;
                }
                如果(获取(AM_PM)== AM){
                    super.set(HOUR_OF_DAY,得到(小时));
                }其他{
                    super.set(HOUR_OF_DAY,得到(小时)+ 12);
                }
            }
            打破;
        }
        案例YEAR:{
            super.set(YEAR,internalGet(YEAR)+量);
            如果(internalGet(月)== 11安培;&安培; internalGet(DAY_OF_MONTH)== 30
                    &功放;&安培; !isLeepYear(internalGet(年))){
                super.set(DAY_OF_MONTH,29);
            }
            打破;
        }
        案例MINUTE:{
            INT单位= 60;
            INT M =(internalGet(分)+量)%单位;
            如果(M小于0){
                M + =单位;
            }
            super.set(分,米);
            打破;
        }
        第二案:{
            INT单位= 60;
            INT S =(internalGet(第二次)+量)%单位;
            如果(S℃,){
                S + =单位;
            }
            super.set(第二,S);
            打破;
        }
        案例微差:{
            INT单位= 1000;
            诠释毫秒=(internalGet(微差)+量)%单位;
            如果(毫秒℃,){
                MS + =单位;
            }
            super.set(毫秒毫秒);
            打破;
        }        案例HOUR:{
            super.set(HOUR,(internalGet(HOUR)的量+)%12);
            如果(internalGet(HOUR)小于0){
                域[HOUR] + = 12;
            }
            如果(internalGet(AM_PM)== AM){
                super.set(HOUR_OF_DAY,internalGet(HOUR));
            }其他{
                super.set(HOUR_OF_DAY,internalGet(HOUR)+ 12);
            }            打破;
        }
        案例HOUR_OF_DAY:{
            域[HOUR_OF_DAY] =(internalGet(HOUR_OF_DAY)+量)%24;
            如果(internalGet(HOUR_OF_DAY)小于0){
                域[HOUR_OF_DAY] + = 24;
            }
            如果(internalGet(HOUR_OF_DAY)下; 12){
                域[AM_PM] = AM;
                域[HOUR] = internalGet(HOUR_OF_DAY);
            }其他{
                域[AM_PM] = PM;
                域[HOUR] = internalGet(HOUR_OF_DAY) - 12;
            }        }
        案例MONTH:{
            INT月=(internalGet(月)+量)%12;
            如果(星期一及小于0){
                周一+ = 12;
            }
            super.set(月,星期一);            INT monthLen = jalaliDaysInMonth [问];
            如果(internalGet(月)== 11安培;&安培; isLeepYear(internalGet(年))){
                monthLen = 30;
            }
            如果(internalGet(DAY_OF_MONTH)GT; monthLen){
                super.set(DAY_OF_MONTH,monthLen);
            }
            打破;
        }
        案例DAY_OF_MONTH:{
            INT单元= 0;
            如果(0℃=得到(月)及和放大器;得到(月)LT = 5){
                单位= 31;
            }
            如果(6≤=得到(月)及和放大器;得到(月)LT = 10){
                单位= 30;
            }
            如果(获取(月)== 11){
                如果(isLeepYear(获取(年))){
                    单位= 30;
                }其他{
                    单位= 29;
                }
            }
            INT D =(获得(DAY_OF_MONTH)+量)%单位;
            如果(D℃,){
                D + =单位;
            }
            super.set(DAY_OF_MONTH,D);
            打破;        }
        案例WEEK_OF_YEAR:{
            打破;
        }
        案例DAY_OF_YEAR:{
            INT单位=(isLeepYear(internalGet(年))366:365);
            INT DAYOFYEAR =(internalGet(DAY_OF_YEAR)+量)%单位;
            DAYOFYEAR =(DAYOFYEAR大于0)? DAYOFYEAR:DAYOFYEAR +单位;
            月整型= 0,温度= 0;
            而(DAYOFYEAR>临时){
                温度+ = jalaliDaysInMonth [本月++];
            }
            super.set(月,--month);
            super.set(DAY_OF_MONTH,jalaliDaysInMonth [internalGet(月)]
                     - (温度 - DAYOFYEAR));
            打破;
        }
        案例DAY_OF_WEEK:{
            INT指数=量7%;
            如果(指数℃下){
                指数+ = 7;
            }
            INT I = 0;
            同时,(我!=指数){
                如果(internalGet(DAY_OF_WEEK)==星期五){
                    加(DAY_OF_MONTH,-6);
                }其他{
                    加(DAY_OF_MONTH,+ 1);
                }
                我++;
            }
            打破;
        }        默认:
            抛出新抛出:IllegalArgumentException();
        }    }    @覆盖
    公众诠释getMinimum(INT场){
        返回MIN_VALUES [现场]
    }    @覆盖
    公众诠释getMaximum(INT场){
        返回MAX_VALUES [现场]
    }    @覆盖
    公众诠释getGreatestMinimum(INT场){
        返回MIN_VALUES [现场]
    }    @覆盖
    公众诠释getLeastMaximum(INT场){
        返回LEAST_MAX_VALUES [现场]
    }    公共静态类年月日{        公共年月日(INT年,月整型,诠释日期){
            this.year =年;
            this.month =月;
            this.date =日期;
        }        私人诠释年;
        私人诠释月;
        私人诠释日期;        公众诠释了getYear(){
            返回年;
        }        公共无效setYear(INT年){
            this.year =年;
        }        公众诠释的getMonth(){
            返回一个月;
        }        公共无效setMonth(INT一个月){
            this.month =月;
        }        公众诠释GETDATE(){
            归期;
        }        公共无效的setDate(INT日期){
            this.date =日期;
        }        公共字符串的toString(){
            返回得到年()+/+得到月()+/+ GETDATE();
        }
    }
}

Is there any library or algorithm to convert Shamsi(Jalali) to Gregorian date in Java?

解决方案

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

public class JalaliCalendar extends Calendar {
    public static int gregorianDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31,
            31, 30, 31, 30, 31 };
    public static int jalaliDaysInMonth[] = { 31, 31, 31, 31, 31, 31, 30, 30,
            30, 30, 30, 29 };

    public final static int FARVARDIN = 0;
    public final static int ORDIBEHESHT = 1;
    public final static int KHORDAD = 2;
    public final static int TIR = 3;
    public final static int MORDAD = 4;
    public final static int SHAHRIVAR = 5;
    public final static int MEHR = 6;
    public final static int ABAN = 7;
    public final static int AZAR = 8;
    public final static int DEY = 9;
    public final static int BAHMAN = 10;
    public final static int ESFAND = 11;

    private static TimeZone timeZone = TimeZone.getDefault();
    private static boolean isTimeSeted = false;

    private static final int ONE_SECOND = 1000;
    private static final int ONE_MINUTE = 60 * ONE_SECOND;
    private static final int ONE_HOUR = 60 * ONE_MINUTE;
    private static final long ONE_DAY = 24 * ONE_HOUR;
    static final int BCE = 0;
    static final int CE = 1;
    public static final int AD = 1;
    private GregorianCalendar cal;

    static final int MIN_VALUES[] = { BCE, 1, FARVARDIN, 1, 0, 1, 1, SATURDAY,
            1, AM, 0, 0, 0, 0, 0, -13 * ONE_HOUR, 0 };

    static final int LEAST_MAX_VALUES[] = { CE, 292269054, ESFAND, 52, 4, 28,
            365, FRIDAY, 4, PM, 11, 23, 59, 59, 999, 14 * ONE_HOUR,
            20 * ONE_MINUTE };

    static final int MAX_VALUES[] = { CE, 292278994, ESFAND, 53, 6, 31, 366,
            FRIDAY, 6, PM, 11, 23, 59, 59, 999, 14 * ONE_HOUR, 2 * ONE_HOUR };

    public JalaliCalendar() {
        this(TimeZone.getDefault(), Locale.getDefault());
    }

    public JalaliCalendar(TimeZone zone) {
        this(zone, Locale.getDefault());
    }

    public JalaliCalendar(Locale aLocale) {
        this(TimeZone.getDefault(), aLocale);
    }

    public JalaliCalendar(TimeZone zone, Locale aLocale) {

        super(zone, aLocale);
        timeZone = zone;
        Calendar calendar = Calendar.getInstance(zone, aLocale);

        YearMonthDate yearMonthDate = new YearMonthDate(calendar.get(YEAR),
                calendar.get(MONTH), calendar.get(DATE));
        yearMonthDate = gregorianToJalali(yearMonthDate);
        set(yearMonthDate.getYear(), yearMonthDate.getMonth(),
                yearMonthDate.getDate());
        complete();

    }

    public Date getGregorianDate(String jalaliDate) {
        String[] arr = jalaliDate.split("/");

        YearMonthDate jalali = new YearMonthDate(Integer.parseInt(arr[0]),
                Integer.parseInt(arr[1]) - 1, Integer.parseInt(arr[2]));

        YearMonthDate gDate = jalaliToGregorian(jalali);

        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(gDate.getYear(), gDate.getMonth(), gDate.getDate());

        Date dt = cal.getTime();

        return dt;
    }

    public String getJalaliDate(Date gDate) {

        Calendar gCal = Calendar.getInstance();

        gCal.clear();

        gCal.setTime(gDate);
        Date dt = gCal.getTime();
        int myYear = gCal.get(Calendar.YEAR);
        int myMonth = gCal.get(Calendar.MONTH);
        int myDay = gCal.get(Calendar.DAY_OF_MONTH);
        YearMonthDate gMyDate = new YearMonthDate(myYear, myMonth, myDay);

        YearMonthDate jDate = gregorianToJalali(gMyDate);

        String jalali = jDate.year + "/" + (jDate.month + 1) + "/" + jDate.date;

        return jalali;
    }

    public JalaliCalendar(int year, int month, int dayOfMonth) {
        this(year, month, dayOfMonth, 0, 0, 0, 0);
    }

    public JalaliCalendar(int year, int month, int dayOfMonth, int hourOfDay,
            int minute) {
        this(year, month, dayOfMonth, hourOfDay, minute, 0, 0);
    }

    public JalaliCalendar(int year, int month, int dayOfMonth, int hourOfDay,
            int minute, int second) {
        this(year, month, dayOfMonth, hourOfDay, minute, second, 0);
    }

    JalaliCalendar(int year, int month, int dayOfMonth, int hourOfDay,
            int minute, int second, int millis) {
        super();

        this.set(YEAR, year);
        this.set(MONTH, month);
        this.set(DAY_OF_MONTH, dayOfMonth);

        if (hourOfDay >= 12 && hourOfDay <= 23) {

            this.set(AM_PM, PM);
            this.set(HOUR, hourOfDay - 12);
        } else {
            this.set(HOUR, hourOfDay);
            this.set(AM_PM, AM);
        }

        this.set(HOUR_OF_DAY, hourOfDay);
        this.set(MINUTE, minute);
        this.set(SECOND, second);

        this.set(MILLISECOND, millis);

        YearMonthDate yearMonthDate = jalaliToGregorian(new YearMonthDate(
                fields[1], fields[2], fields[5]));
        cal = new GregorianCalendar(yearMonthDate.getYear(),
                yearMonthDate.getMonth(), yearMonthDate.getDate(), hourOfDay,
                minute, second);
        time = cal.getTimeInMillis();

        isTimeSeted = true;
    }

    public static YearMonthDate gregorianToJalali(YearMonthDate gregorian) {

        if (gregorian.getMonth() > 11 || gregorian.getMonth() < -11) {
            throw new IllegalArgumentException();
        }
        int jalaliYear;
        int jalaliMonth;
        int jalaliDay;

        int gregorianDayNo, jalaliDayNo;
        int jalaliNP;
        int i;

        gregorian.setYear(gregorian.getYear() - 1600);
        gregorian.setDate(gregorian.getDate() - 1);

        gregorianDayNo = 365 * gregorian.getYear()
                + (int) Math.floor((gregorian.getYear() + 3) / 4)
                - (int) Math.floor((gregorian.getYear() + 99) / 100)
                + (int) Math.floor((gregorian.getYear() + 399) / 400);
        for (i = 0; i < gregorian.getMonth(); ++i) {
            gregorianDayNo += gregorianDaysInMonth[i];
        }

        if (gregorian.getMonth() > 1
                && ((gregorian.getYear() % 4 == 0 && gregorian.getYear() % 100 != 0) || (gregorian
                        .getYear() % 400 == 0))) {
            ++gregorianDayNo;
        }

        gregorianDayNo += gregorian.getDate();

        jalaliDayNo = gregorianDayNo - 79;

        jalaliNP = (int) Math.floor(jalaliDayNo / 12053);
        jalaliDayNo = jalaliDayNo % 12053;

        jalaliYear = 979 + 33 * jalaliNP + 4 * (int) (jalaliDayNo / 1461);
        jalaliDayNo = jalaliDayNo % 1461;

        if (jalaliDayNo >= 366) {
            jalaliYear += (int) Math.floor((jalaliDayNo - 1) / 365);
            jalaliDayNo = (jalaliDayNo - 1) % 365;
        }

        for (i = 0; i < 11 && jalaliDayNo >= jalaliDaysInMonth[i]; ++i) {
            jalaliDayNo -= jalaliDaysInMonth[i];
        }
        jalaliMonth = i;
        jalaliDay = jalaliDayNo + 1;

        return new YearMonthDate(jalaliYear, jalaliMonth, jalaliDay);
    }

    public static YearMonthDate jalaliToGregorian(YearMonthDate jalali) {
        if (jalali.getMonth() > 11 || jalali.getMonth() < -11) {
            throw new IllegalArgumentException();
        }

        int gregorianYear;
        int gregorianMonth;
        int gregorianDay;

        int gregorianDayNo, jalaliDayNo;
        int leap;

        int i;
        jalali.setYear(jalali.getYear() - 979);
        jalali.setDate(jalali.getDate() - 1);

        jalaliDayNo = 365 * jalali.getYear() + (int) (jalali.getYear() / 33)
                * 8 + (int) Math.floor(((jalali.getYear() % 33) + 3) / 4);
        for (i = 0; i < jalali.getMonth(); ++i) {
            jalaliDayNo += jalaliDaysInMonth[i];
        }

        jalaliDayNo += jalali.getDate();

        gregorianDayNo = jalaliDayNo + 79;

        gregorianYear = 1600 + 400 * (int) Math.floor(gregorianDayNo / 146097); /*
                                                                                 * 146097
                                                                                 * =
                                                                                 * 365
                                                                                 * *
                                                                                 * 400
                                                                                 * +
                                                                                 * 400
                                                                                 * /
                                                                                 * 4
                                                                                 * -
                                                                                 * 400
                                                                                 * /
                                                                                 * 100
                                                                                 * +
                                                                                 * 400
                                                                                 * /
                                                                                 * 400
                                                                                 */
        gregorianDayNo = gregorianDayNo % 146097;

        leap = 1;
        if (gregorianDayNo >= 36525) /* 36525 = 365*100 + 100/4 */{
            gregorianDayNo--;
            gregorianYear += 100 * (int) Math.floor(gregorianDayNo / 36524); /*
                                                                             * 36524
                                                                             * =
                                                                             * 365
                                                                             * *
                                                                             * 100
                                                                             * +
                                                                             * 100
                                                                             * /
                                                                             * 4
                                                                             * -
                                                                             * 100
                                                                             * /
                                                                             * 100
                                                                             */
            gregorianDayNo = gregorianDayNo % 36524;

            if (gregorianDayNo >= 365) {
                gregorianDayNo++;
            } else {
                leap = 0;
            }
        }

        gregorianYear += 4 * (int) Math.floor(gregorianDayNo / 1461); /*
                                                                     * 1461 =
                                                                     * 365*4 +
                                                                     * 4/4
                                                                     */
        gregorianDayNo = gregorianDayNo % 1461;

        if (gregorianDayNo >= 366) {
            leap = 0;

            gregorianDayNo--;
            gregorianYear += (int) Math.floor(gregorianDayNo / 365);
            gregorianDayNo = gregorianDayNo % 365;
        }

        for (i = 0; gregorianDayNo >= gregorianDaysInMonth[i]
                + ((i == 1 && leap == 1) ? i : 0); i++) {
            gregorianDayNo -= gregorianDaysInMonth[i]
                    + ((i == 1 && leap == 1) ? i : 0);
        }
        gregorianMonth = i;
        gregorianDay = gregorianDayNo + 1;

        return new YearMonthDate(gregorianYear, gregorianMonth, gregorianDay);

    }

    public static int weekOfYear(int dayOfYear, int year) {
        switch (dayOfWeek(JalaliCalendar.jalaliToGregorian(new YearMonthDate(
                year, 0, 1)))) {
        case 2:
            dayOfYear++;
            break;
        case 3:
            dayOfYear += 2;
            break;
        case 4:
            dayOfYear += 3;
            break;
        case 5:
            dayOfYear += 4;
            break;
        case 6:
            dayOfYear += 5;
            break;
        case 7:
            dayOfYear--;
            break;
        }
        ;
        dayOfYear = (int) Math.floor(dayOfYear / 7);
        return dayOfYear + 1;
    }

    public static int dayOfWeek(YearMonthDate yearMonthDate) {

        Calendar cal = new GregorianCalendar(yearMonthDate.getYear(),
                yearMonthDate.getMonth(), yearMonthDate.getDate());
        return cal.get(DAY_OF_WEEK);

    }

    public static boolean isLeepYear(int year) {
        // Algorithm from www.wikipedia.com
        if ((year % 33 == 1 || year % 33 == 5 || year % 33 == 9
                || year % 33 == 13 || year % 33 == 17 || year % 33 == 22
                || year % 33 == 26 || year % 33 == 30)) {
            return true;
        } else
            return false;
    }

    @Override
    protected void computeTime() {

        if (!isTimeSet && !isTimeSeted) {
            Calendar cal = GregorianCalendar.getInstance(timeZone);
            if (!isSet(HOUR_OF_DAY)) {
                super.set(HOUR_OF_DAY, cal.get(HOUR_OF_DAY));
            }
            if (!isSet(HOUR)) {
                super.set(HOUR, cal.get(HOUR));
            }
            if (!isSet(MINUTE)) {
                super.set(MINUTE, cal.get(MINUTE));
            }
            if (!isSet(SECOND)) {
                super.set(SECOND, cal.get(SECOND));
            }
            if (!isSet(MILLISECOND)) {
                super.set(MILLISECOND, cal.get(MILLISECOND));
            }
            if (!isSet(ZONE_OFFSET)) {
                super.set(ZONE_OFFSET, cal.get(ZONE_OFFSET));
            }
            if (!isSet(DST_OFFSET)) {
                super.set(DST_OFFSET, cal.get(DST_OFFSET));
            }
            if (!isSet(AM_PM)) {
                super.set(AM_PM, cal.get(AM_PM));
            }

            if (internalGet(HOUR_OF_DAY) >= 12
                    && internalGet(HOUR_OF_DAY) <= 23) {
                super.set(AM_PM, PM);
                super.set(HOUR, internalGet(HOUR_OF_DAY) - 12);
            } else {
                super.set(HOUR, internalGet(HOUR_OF_DAY));
                super.set(AM_PM, AM);
            }

            YearMonthDate yearMonthDate = jalaliToGregorian(new YearMonthDate(
                    internalGet(YEAR), internalGet(MONTH),
                    internalGet(DAY_OF_MONTH)));
            cal.set(yearMonthDate.getYear(), yearMonthDate.getMonth(),
                    yearMonthDate.getDate(), internalGet(HOUR_OF_DAY),
                    internalGet(MINUTE), internalGet(SECOND));
            time = cal.getTimeInMillis();

        } else if (!isTimeSet && isTimeSeted) {
            if (internalGet(HOUR_OF_DAY) >= 12
                    && internalGet(HOUR_OF_DAY) <= 23) {
                super.set(AM_PM, PM);
                super.set(HOUR, internalGet(HOUR_OF_DAY) - 12);
            } else {
                super.set(HOUR, internalGet(HOUR_OF_DAY));
                super.set(AM_PM, AM);
            }
            cal = new GregorianCalendar();
            super.set(ZONE_OFFSET, timeZone.getRawOffset());
            super.set(DST_OFFSET, timeZone.getDSTSavings());
            YearMonthDate yearMonthDate = jalaliToGregorian(new YearMonthDate(
                    internalGet(YEAR), internalGet(MONTH),
                    internalGet(DAY_OF_MONTH)));
            cal.set(yearMonthDate.getYear(), yearMonthDate.getMonth(),
                    yearMonthDate.getDate(), internalGet(HOUR_OF_DAY),
                    internalGet(MINUTE), internalGet(SECOND));
            time = cal.getTimeInMillis();
        }
    }

    public void set(int field, int value) {
        switch (field) {
        case DATE: {
            super.set(field, 0);
            add(field, value);
            break;
        }
        case MONTH: {
            if (value > 11) {
                super.set(field, 11);
                add(field, value - 11);
            } else if (value < 0) {
                super.set(field, 0);
                add(field, value);
            } else {
                super.set(field, value);
            }
            break;
        }
        case DAY_OF_YEAR: {
            if (isSet(YEAR) && isSet(MONTH) && isSet(DAY_OF_MONTH)) {
                super.set(YEAR, internalGet(YEAR));
                super.set(MONTH, 0);
                super.set(DATE, 0);
                add(field, value);
            } else {
                super.set(field, value);
            }
            break;
        }
        case WEEK_OF_YEAR: {
            if (isSet(YEAR) && isSet(MONTH) && isSet(DAY_OF_MONTH)) {
                add(field, value - get(WEEK_OF_YEAR));
            } else {
                super.set(field, value);
            }
            break;
        }
        case WEEK_OF_MONTH: {
            if (isSet(YEAR) && isSet(MONTH) && isSet(DAY_OF_MONTH)) {
                add(field, value - get(WEEK_OF_MONTH));
            } else {
                super.set(field, value);
            }
            break;
        }
        case DAY_OF_WEEK: {
            if (isSet(YEAR) && isSet(MONTH) && isSet(DAY_OF_MONTH)) {
                add(DAY_OF_WEEK, value % 7 - get(DAY_OF_WEEK));
            } else {
                super.set(field, value);
            }
            break;
        }
        case HOUR_OF_DAY:
        case HOUR:
        case MINUTE:
        case SECOND:
        case MILLISECOND:
        case ZONE_OFFSET:
        case DST_OFFSET: {
            if (isSet(YEAR) && isSet(MONTH) && isSet(DATE) && isSet(HOUR)
                    && isSet(HOUR_OF_DAY) && isSet(MINUTE) && isSet(SECOND)
                    && isSet(MILLISECOND)) {
                cal = new GregorianCalendar();
                YearMonthDate yearMonthDate = jalaliToGregorian(new YearMonthDate(
                        internalGet(YEAR), internalGet(MONTH),
                        internalGet(DATE)));
                cal.set(yearMonthDate.getYear(), yearMonthDate.getMonth(),
                        yearMonthDate.getDate(), internalGet(HOUR_OF_DAY),
                        internalGet(MINUTE), internalGet(SECOND));
                cal.set(field, value);
                yearMonthDate = gregorianToJalali(new YearMonthDate(
                        cal.get(YEAR), cal.get(MONTH), cal.get(DATE)));
                super.set(YEAR, yearMonthDate.getYear());
                super.set(MONTH, yearMonthDate.getMonth());
                super.set(DATE, yearMonthDate.getDate());
                super.set(HOUR_OF_DAY, cal.get(HOUR_OF_DAY));
                super.set(MINUTE, cal.get(MINUTE));
                super.set(SECOND, cal.get(SECOND));

            } else {
                super.set(field, value);
            }
            break;
        }

        default: {
            super.set(field, value);
        }
        }
    }

    @Override
    protected void computeFields() {
        boolean temp = isTimeSet;
        if (!areFieldsSet) {
            setMinimalDaysInFirstWeek(1);
            setFirstDayOfWeek(7);

            // Day_Of_Year
            int dayOfYear = 0;
            int index = 0;

            while (index < fields[2]) {
                dayOfYear += jalaliDaysInMonth[index++];
            }
            dayOfYear += fields[5];
            super.set(DAY_OF_YEAR, dayOfYear);
            // ***

            // Day_of_Week
            super.set(DAY_OF_WEEK,
                    dayOfWeek(jalaliToGregorian(new YearMonthDate(fields[1],
                            fields[2], fields[5]))));
            // ***

            // Day_Of_Week_In_Month
            if (0 < fields[5] && fields[5] < 8) {
                super.set(DAY_OF_WEEK_IN_MONTH, 1);
            }

            if (7 < fields[5] && fields[5] < 15) {
                super.set(DAY_OF_WEEK_IN_MONTH, 2);
            }

            if (14 < fields[5] && fields[5] < 22) {
                super.set(DAY_OF_WEEK_IN_MONTH, 3);
            }

            if (21 < fields[5] && fields[5] < 29) {
                super.set(DAY_OF_WEEK_IN_MONTH, 4);
            }

            if (28 < fields[5] && fields[5] < 32) {
                super.set(DAY_OF_WEEK_IN_MONTH, 5);
            }
            // ***

            // Week_Of_Year
            super.set(WEEK_OF_YEAR, weekOfYear(fields[6], fields[1]));
            // ***

            // Week_Of_Month
            super.set(WEEK_OF_MONTH, weekOfYear(fields[6], fields[1])
                    - weekOfYear(fields[6] - fields[5], fields[1]) + 1);
            //

            isTimeSet = temp;
        }
    }

    @Override
    public void add(int field, int amount) {

        if (field == MONTH) {
            amount += get(MONTH);
            add(YEAR, amount / 12);
            super.set(MONTH, amount % 12);
            if (get(DAY_OF_MONTH) > jalaliDaysInMonth[amount % 12]) {
                super.set(DAY_OF_MONTH, jalaliDaysInMonth[amount % 12]);
                if (get(MONTH) == 11 && isLeepYear(get(YEAR))) {
                    super.set(DAY_OF_MONTH, 30);
                }
            }
            complete();

        } else if (field == YEAR) {

            super.set(YEAR, get(YEAR) + amount);
            if (get(DAY_OF_MONTH) == 30 && get(MONTH) == 11
                    && !isLeepYear(get(YEAR))) {
                super.set(DAY_OF_MONTH, 29);
            }

            complete();
        } else {
            YearMonthDate yearMonthDate = jalaliToGregorian(new YearMonthDate(
                    get(YEAR), get(MONTH), get(DATE)));
            Calendar gc = new GregorianCalendar(yearMonthDate.getYear(),
                    yearMonthDate.getMonth(), yearMonthDate.getDate(),
                    get(HOUR_OF_DAY), get(MINUTE), get(SECOND));
            gc.add(field, amount);
            yearMonthDate = gregorianToJalali(new YearMonthDate(gc.get(YEAR),
                    gc.get(MONTH), gc.get(DATE)));
            super.set(YEAR, yearMonthDate.getYear());
            super.set(MONTH, yearMonthDate.getMonth());
            super.set(DATE, yearMonthDate.getDate());
            super.set(HOUR_OF_DAY, gc.get(HOUR_OF_DAY));
            super.set(MINUTE, gc.get(MINUTE));
            super.set(SECOND, gc.get(SECOND));
            complete();
        }

    }

    @Override
    public void roll(int field, boolean up) {
        roll(field, up ? +1 : -1);
    }

    @Override
    public void roll(int field, int amount) {
        if (amount == 0) {
            return;
        }

        if (field < 0 || field >= ZONE_OFFSET) {
            throw new IllegalArgumentException();
        }

        complete();

        switch (field) {
        case AM_PM: {
            if (amount % 2 != 0) {
                if (internalGet(AM_PM) == AM) {
                    fields[AM_PM] = PM;
                } else {
                    fields[AM_PM] = AM;
                }
                if (get(AM_PM) == AM) {
                    super.set(HOUR_OF_DAY, get(HOUR));
                } else {
                    super.set(HOUR_OF_DAY, get(HOUR) + 12);
                }
            }
            break;
        }
        case YEAR: {
            super.set(YEAR, internalGet(YEAR) + amount);
            if (internalGet(MONTH) == 11 && internalGet(DAY_OF_MONTH) == 30
                    && !isLeepYear(internalGet(YEAR))) {
                super.set(DAY_OF_MONTH, 29);
            }
            break;
        }
        case MINUTE: {
            int unit = 60;
            int m = (internalGet(MINUTE) + amount) % unit;
            if (m < 0) {
                m += unit;
            }
            super.set(MINUTE, m);
            break;
        }
        case SECOND: {
            int unit = 60;
            int s = (internalGet(SECOND) + amount) % unit;
            if (s < 0) {
                s += unit;
            }
            super.set(SECOND, s);
            break;
        }
        case MILLISECOND: {
            int unit = 1000;
            int ms = (internalGet(MILLISECOND) + amount) % unit;
            if (ms < 0) {
                ms += unit;
            }
            super.set(MILLISECOND, ms);
            break;
        }

        case HOUR: {
            super.set(HOUR, (internalGet(HOUR) + amount) % 12);
            if (internalGet(HOUR) < 0) {
                fields[HOUR] += 12;
            }
            if (internalGet(AM_PM) == AM) {
                super.set(HOUR_OF_DAY, internalGet(HOUR));
            } else {
                super.set(HOUR_OF_DAY, internalGet(HOUR) + 12);
            }

            break;
        }
        case HOUR_OF_DAY: {
            fields[HOUR_OF_DAY] = (internalGet(HOUR_OF_DAY) + amount) % 24;
            if (internalGet(HOUR_OF_DAY) < 0) {
                fields[HOUR_OF_DAY] += 24;
            }
            if (internalGet(HOUR_OF_DAY) < 12) {
                fields[AM_PM] = AM;
                fields[HOUR] = internalGet(HOUR_OF_DAY);
            } else {
                fields[AM_PM] = PM;
                fields[HOUR] = internalGet(HOUR_OF_DAY) - 12;
            }

        }
        case MONTH: {
            int mon = (internalGet(MONTH) + amount) % 12;
            if (mon < 0) {
                mon += 12;
            }
            super.set(MONTH, mon);

            int monthLen = jalaliDaysInMonth[mon];
            if (internalGet(MONTH) == 11 && isLeepYear(internalGet(YEAR))) {
                monthLen = 30;
            }
            if (internalGet(DAY_OF_MONTH) > monthLen) {
                super.set(DAY_OF_MONTH, monthLen);
            }
            break;
        }
        case DAY_OF_MONTH: {
            int unit = 0;
            if (0 <= get(MONTH) && get(MONTH) <= 5) {
                unit = 31;
            }
            if (6 <= get(MONTH) && get(MONTH) <= 10) {
                unit = 30;
            }
            if (get(MONTH) == 11) {
                if (isLeepYear(get(YEAR))) {
                    unit = 30;
                } else {
                    unit = 29;
                }
            }
            int d = (get(DAY_OF_MONTH) + amount) % unit;
            if (d < 0) {
                d += unit;
            }
            super.set(DAY_OF_MONTH, d);
            break;

        }
        case WEEK_OF_YEAR: {
            break;
        }
        case DAY_OF_YEAR: {
            int unit = (isLeepYear(internalGet(YEAR)) ? 366 : 365);
            int dayOfYear = (internalGet(DAY_OF_YEAR) + amount) % unit;
            dayOfYear = (dayOfYear > 0) ? dayOfYear : dayOfYear + unit;
            int month = 0, temp = 0;
            while (dayOfYear > temp) {
                temp += jalaliDaysInMonth[month++];
            }
            super.set(MONTH, --month);
            super.set(DAY_OF_MONTH, jalaliDaysInMonth[internalGet(MONTH)]
                    - (temp - dayOfYear));
            break;
        }
        case DAY_OF_WEEK: {
            int index = amount % 7;
            if (index < 0) {
                index += 7;
            }
            int i = 0;
            while (i != index) {
                if (internalGet(DAY_OF_WEEK) == FRIDAY) {
                    add(DAY_OF_MONTH, -6);
                } else {
                    add(DAY_OF_MONTH, +1);
                }
                i++;
            }
            break;
        }

        default:
            throw new IllegalArgumentException();
        }

    }

    @Override
    public int getMinimum(int field) {
        return MIN_VALUES[field];
    }

    @Override
    public int getMaximum(int field) {
        return MAX_VALUES[field];
    }

    @Override
    public int getGreatestMinimum(int field) {
        return MIN_VALUES[field];
    }

    @Override
    public int getLeastMaximum(int field) {
        return LEAST_MAX_VALUES[field];
    }

    public static class YearMonthDate {

        public YearMonthDate(int year, int month, int date) {
            this.year = year;
            this.month = month;
            this.date = date;
        }

        private int year;
        private int month;
        private int date;

        public int getYear() {
            return year;
        }

        public void setYear(int year) {
            this.year = year;
        }

        public int getMonth() {
            return month;
        }

        public void setMonth(int month) {
            this.month = month;
        }

        public int getDate() {
            return date;
        }

        public void setDate(int date) {
            this.date = date;
        }

        public String toString() {
            return getYear() + "/" + getMonth() + "/" + getDate();
        }
    }
}

这篇关于是否有任何库或算法来沙姆西(贾拉利)转换成公历日期在Java中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆