4

我有 jdk java 版本“1.8.0_45”,我正在使用 joda time api (joda-time-2.7.jar)

By using Joda time api i am getting a wrong date.

By using Jdk 8 hijri date api i am getting a correct date.

我需要使用 java api 将公历日期转换为回历日期。

我的示例测试类如下:

import org.joda.time.*;
import org.joda.time.chrono.*;
import java.time.*;
import java.time.chrono.HijrahChronology;
import java.util.*;
public class Test {
    public static void main(String[] args) throws Exception {
        DateTime dtISO = new DateTime();
        System.out.println("dtISO = "+dtISO);
        DateTime dtIslamic = dtISO.withChronology(IslamicChronology.getInstance(DateTimeZone.UTC  ));
        System.out.println(dtIslamic.getYear()+"-" +dtIslamic.getMonthOfYear()+ "-"+ dtIslamic.getDayOfMonth());
        java.time.chrono.HijrahDate hijradate = java.time.chrono.HijrahDate.now();
        System.out.println("hijradate "+hijradate);
    }
} 

这个类的输出是

C:\>java Test
dtISO = 2015-05-24T09:44:51.704+04:00
1436-8-5
hijradate Hijrah-umalqura AH 1436-08-06

你能告诉我joda api是正确的还是错误的?

我的生产服务器有 JDK1.6,我目前无法将其升级到 1.8,所以请让我知道您的建议以获得正确的回历日期....等待您的回复....

4

3 回答 3

2

您在 JodaTime 和 JDK8 之间看到的差异是因为它们使用回历日历的不同实现。有多种算法可以计算(近似)回历日期。

Jdk8 的 HijrahChoronology 使用 Umm-AlQura 日历的实现,它与http://www.ummulqura.org.sa/中定义的沙特阿拉伯官方 Hijri 日历非常匹配。

JodaTime IslamChronology 有不同的实现,您可以使用其工厂方法进行选择,请参阅http://joda-time.sourceforge.net/apidocs/org/joda/time/chrono/IslamicChronology.html

因此,这实际上取决于系统受众。如果您在沙特阿拉伯或任何依赖 UmmAlQura 日历的国家/地区,请坚持使用 JDK8 的实施。

于 2015-12-17T14:56:42.613 回答
0

我在http://junaedhalim.blogspot.com/2010/01/hijri-calendar-in-java-using-kuwaiti.html上找到了这段代码,希望它对你有所帮助

导入 java.util.Calendar;导入 java.util.Date;

/**
 *
 * @author junaed
 */
public class HijriCalendar
{

    private int[] userDateG;
    private int[] userDateH;

    private WaqtMidlet midlet;
    private Calendar cal;
    private int currentHijriDate;
    private int currentHijriMonth;
    private int currentHijriYear;
    public static final String[] HIJRI_MONTHS =
    {
        "Muharram", "Safar", "Rabi' al-awwal", "Rabi' al-thani", "Jumada al-awwal",
        "Jumada al-thani", "Rajab", "Sha'aban", "Ramadan", "Shawwal", "Dhu al-Qi'dah", "Dhu al-Hijjah"
    };
    public static final int[] BASE_DATE_G =
    {
        18, 11, 2009, 0, 0
    };
    public static final int[] BASE_DATE_H =
    {
        1, 0, 1431, 0, 0
    };
    public HijriCalendar(WaqtMidlet midlet)
    {
        this.midlet = midlet;
        cal = Calendar.getInstance();
        Date date = new Date();
        cal.setTime(date);
    }

    private void updateDefinedTime()
    {
        String uTimeH = midlet.getRmsManager().getString(ApplicationConstants.RMS_HIJRI_DATE);
//        String uTimeH = "";
        if (uTimeH == null || uTimeH.equalsIgnoreCase(""))
        {
            userDateG = ApplicationConstants.BASE_DATE_G;
            userDateH = ApplicationConstants.BASE_DATE_H;
        }
        else
        {
            System.out.println("uTimeH = " + uTimeH);
            int date = Integer.parseInt(uTimeH.substring(0, uTimeH.indexOf(';')));
            String rest = uTimeH.substring(uTimeH.indexOf(';') + 1);
            int month = Integer.parseInt(rest.substring(0, rest.indexOf(';')));
            rest = rest.substring(rest.indexOf(';') + 1);
            int year = Integer.parseInt(rest.substring(0, rest.indexOf(';')));
            rest = rest.substring(rest.indexOf(';') + 1);
            int hour = Integer.parseInt(rest.substring(0, rest.indexOf(';')));
            rest = rest.substring(rest.indexOf(';') + 1);
            int minute = Integer.parseInt(rest);

            userDateH = new int[]
                    {
                        date, month, year, hour, minute
                    };

//            String uTimeG = "";
            String uTimeG = midlet.getRmsManager().getString(ApplicationConstants.RMS_GREGORIAN_DATE);
            System.out.println("uTimeG = " + uTimeG);
            date  = Integer.parseInt(uTimeG.substring(0, uTimeG.indexOf(';')));
            rest = uTimeG.substring(uTimeG.indexOf(';') + 1);
            month = Integer.parseInt(rest.substring(0, rest.indexOf(';')));
            rest = rest.substring(rest.indexOf(';') + 1);
            year = Integer.parseInt(rest.substring(0, rest.indexOf(';')));

            userDateG = new int[]
                    {
                        date, month, year, hour, minute
                    };
        }

        cal.set(Calendar.HOUR_OF_DAY, userDateG[3]);
        cal.set(Calendar.MINUTE, userDateG[4]);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.DATE, userDateG[0]);
        cal.set(Calendar.MONTH, userDateG[1]);
        cal.set(Calendar.YEAR, userDateG[2]);

        currentHijriDate = userDateH[0];
        currentHijriMonth = userDateH[1];
        currentHijriYear = userDateH[2];
    }

    private boolean isALeapYear(int year)
    {
        int modValue = year % 30;
        switch (modValue)
        {
            case 2:
                return true;
            case 5:
                return true;
            case 7:
                return true;
            case 10:
                return true;
            case 13:
                return true;
            case 15:
                return true;
            case 18:
                return true;
            case 21:
                return true;
            case 24:
                return true;
            case 26:
                return true;
            case 29:
                return true;
        }
        return false;
    }

    private int getDaysInThisYear(int year)
    {
        if (isALeapYear(year))
        {
            return 355;
        }
        return 354;
    }

    public int getDaysInThisMonth(int month, int year)
    {
        if (month % 2 != 0)
        {
            return 30;
        }
        else
        {
            if (month == 12)
            {
                if (isALeapYear(year))
                {
                    return 30;
                }
            }
            return 29;
        }
    }

    private void addOneDayToCurrentDate()
    {
        currentHijriDate++;
        if(currentHijriDate >= 29)
        {
            int daysInCurrentMonth = getDaysInThisMonth(currentHijriMonth, currentHijriYear);
            if( currentHijriDate > daysInCurrentMonth)
            {
                currentHijriDate = 1;
                currentHijriMonth++;
                if(currentHijriMonth > 11)
                {
                    currentHijriMonth = 1;
                    currentHijriYear++;
                }
            }

        }
    }

    private void addDays(long days)
    {
        for(long i = 0; i< days; i++)
        {
            addOneDayToCurrentDate();
        }
    }

    public String getCurrentDateStr()
    {
        updateDefinedTime();
        Date date = new Date();
//        int currentTime = calendar.get(Calendar.HOUR_OF_DAY);
        long diff = date.getTime() - cal.getTime().getTime();
        long days = diff / (1000 * 86400);
        addDays(days);
        String ret = currentHijriYear + " "+HIJRI_MONTHS[currentHijriMonth] + ", " + currentHijriDate;
        return ret;
//        return midlet.getRmsManager().getString(ApplicationConstants.RMS_HIJRI_DATE);

    }

}
于 2015-05-24T06:32:52.193 回答
0

尝试使用ICU4J。它的 Calendar 类不扩展 java.util.Calendar,但它们确实可以正确处理回历日期(和许多其他日历系统)。我能够使用 Java 1.6.0_31 使用其IslamCalendar类获得我认为正确的结果:

import java.util.Date;
import java.util.Locale;

import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.IslamicCalendar;

public class HijriDate {
    public static void main(String[] args) {

        java.util.Calendar gregorianCal =
            java.util.Calendar.getInstance(Locale.US);

        System.out.printf("%tF%n", gregorianCal);

        Date date = gregorianCal.getTime();

        Calendar cal = new IslamicCalendar();
        cal.setTime(date);

        System.out.printf("%02d-%02d-%02d%n",
            cal.get(Calendar.YEAR),
            cal.get(Calendar.MONTH) + 1,
            cal.get(Calendar.DAY_OF_MONTH));
    }
}
于 2015-05-25T16:16:31.753 回答