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

Rah*_*hul 5 calendar date hijri java-8 localdate

我想显示斋月2017 年的开始和结束日期。我尝试使用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);
    }

}
Run Code Online (Sandbox Code Playgroud)

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

输出

2017 年斋月

2018-05-16

2018-06-14

我尝试了很多事情,比如减年,或者做时间调整,但没有任何帮助。有人可以提出一种很酷的实现方式吗?

Ole*_*.V. 4

我\xe2\x80\x99m 不确定\xe2\x80\x99s 是否是完美的方法,但这对我有用并且\xe2\x80\x99t 看起来不太复杂:

\n\n
    ramdanDate = ramdanDate.with(ChronoField.YEAR, ramdanDate.get(ChronoField.YEAR) - 1);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
Ramdan 2017\n2017-05-27\n2017-06-24\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑:

\n\n
\n

假设即使(如果你的公历年与斋月的两个实例重叠,找到两者)是需要的......我想不出实现它的方法。你能建议一下吗?

\n
\n\n

将舌头伸直放在嘴里:

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

如果我将 2017 输入到上述方法中,它会给出与之前相同的结果:

\n\n
    printRamdanDates(2017);\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
Ramdan 2017\n2017-05-27\n2017-06-24\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
    printRamdanDates(2000);\n    printRamdanDates(2030);\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
Ramdan 2000\n1999-12-09\n2000-01-07\n2000-11-27\n2000-12-26\nRamdan 2030\n2030-01-05\n2030-02-03\n2030-12-26\n2031-01-23\n
Run Code Online (Sandbox Code Playgroud)\n