使用java api将格里高利日期转换为Hijri日期

时间:2015-05-24 05:52:48

标签: java hijri

我有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,所以请让我知道您的建议以获得正确的日期....等待您的回复....

3 个答案:

答案 0 :(得分:2)

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

Jdk8的HijrahChoronology使用了Umm-AlQura日历的实现,该日历与lock mechanism中定义的沙特阿拉伯官方Hijri日历非常匹配。

JodaTime IslamicChronology有不同的实现,你可以使用它的工厂方法选择http://www.ummulqura.org.sa/

所以它真的取决于系统受众。如果您在沙特阿拉伯或任何依赖于JDK8实施的UmmAlQura日历棒的国家。

答案 1 :(得分:0)

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

import java.util.Calendar; import 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);

    }

}

答案 2 :(得分:0)

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

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