如何在Java 8 Date API中从Hijrah日期中减去Hijrah年

时间:2018-06-24 03:38:37

标签: date java-8 calendar localdate hijri

我想显示Ramadan 2017年的开始和结束日期。我尝试使用Java HijrahChronology类和Java 8及更高版本内置的HijrahDate编写代码。

import java.time.LocalDate;
import java.time.chrono.HijrahDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;

public class Ramdan {

    public static void main(String[] args) {

        HijrahDate ramdanDate = HijrahDate.now().with(ChronoField.DAY_OF_MONTH, 1).with(ChronoField.MONTH_OF_YEAR, 9);

        LocalDate ramdanStart = LocalDate.from(ramdanDate);
        LocalDate ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));

        System.out.println("Ramdan 2017");
        System.out.println(ramdanStart);
        System.out.println(ramdanEnd);
    }

}

但是它显然会打印出当年的日期,即2018年。

  

输出

     

Ramdan 2017

     

2018-05-16

     

2018-06-14

我尝试了很多事情,例如减负,或进行时间调整,但无济于事。有人可以建议实现这一目标的好方法吗?

1 个答案:

答案 0 :(得分:3)

我不确定这是否是完美的方法,但这对我有用,而且看起来并不复杂:

    ramdanDate = ramdanDate.with(ChronoField.YEAR, ramdanDate.get(ChronoField.YEAR) - 1);

在转换为LocalDate之前插入此行,现在可以打印代码:

Ramdan 2017
2017-05-27
2017-06-24

编辑:

  

即使(如果您的公历年份与   斋月的两个实例,两者都需要)...我想不到   实现它的一种方式。你能建议吗?

将舌头伸直放在嘴里

public static void printRamdanDates(int gregorianYear) {
    LocalDate gregDate = LocalDate.ofYearDay(gregorianYear, 1);
    HijrahDate ramdanDate = HijrahDate.from(gregDate)
            .with(ChronoField.DAY_OF_MONTH, 1)
            .with(ChronoField.MONTH_OF_YEAR, 9);
    LocalDate ramdanStart = LocalDate.from(ramdanDate);
    LocalDate ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));
    // if in previous Gregorian year, skip
    while (ramdanEnd.getYear() < gregorianYear) {
        ramdanDate = ramdanDate.with(ChronoField.YEAR, ramdanDate.get(ChronoField.YEAR) + 1);
        ramdanStart = LocalDate.from(ramdanEnd);
        ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));
    }
    if (ramdanStart.getYear() > gregorianYear) { // in following Gregorian year
        System.out.println("No Ramdan in " + gregorianYear);
    } else {
        System.out.println("Ramdan " + gregorianYear);
        do {
            System.out.println(ramdanStart);
            System.out.println(ramdanEnd);
            ramdanDate = ramdanDate.with(ChronoField.YEAR, ramdanDate.get(ChronoField.YEAR) + 1);
            ramdanStart = LocalDate.from(ramdanDate);
            ramdanEnd = LocalDate.from(ramdanDate.with(TemporalAdjusters.lastDayOfMonth()));
        } while (ramdanStart.getYear() == gregorianYear);
    }
}

如果我将2017年用于上述方法,则会得到与以前相同的结果:

    printRamdanDates(2017);

输出:

Ramdan 2017
2017-05-27
2017-06-24

但是,例如,尝试2000年或2030年斋月在公历/ ISO年发生两次。

    printRamdanDates(2000);
    printRamdanDates(2030);

输出:

Ramdan 2000
1999-12-09
2000-01-07
2000-11-27
2000-12-26
Ramdan 2030
2030-01-05
2030-02-03
2030-12-26
2031-01-23