如何从 Java 8 Date API 中的回历日期中减去回历年份
Posted
技术标签:
【中文标题】如何从 Java 8 Date API 中的回历日期中减去回历年份【英文标题】:How to subtract Hijrah year from a Hijrah Date in Java 8 Date API 【发布时间】:2018-12-03 01:01:24 【问题描述】:我想显示Ramadan 2017 的开始和结束日期。我尝试使用 Java 8 及更高版本中内置的 HijrahChronology
和 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 年。
输出
2017 年斋月
2018-05-16
2018-06-14
我尝试了很多方法,比如减年,或者进行时间调整,但没有任何帮助。有人可以提出一个很酷的方法来实现它吗?
【问题讨论】:
Hijrah 和 ISO 年份并不重合,所以即使斋月恰好在 ISO 2017 年发生一次,我想也不能保证总是如此? @OleV.V.好点子。因此,这限制了我们获取任何特定用户输入公历年份的斋月日期。对吗? 至少需要你决定你想要什么,以防你有一个公历年,比如说,与两个斋月的实例重叠。它希望如果这是所需的话,应该可以找到两者,但关键是,我不知道这是否是所需的。 假设即使它是需要的......我想不出一种实现它的方法。你能建议吗? @OleV.V. 【参考方案1】:我不确定这是不是完美的方法,但这对我有用,而且看起来并不复杂:
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
【讨论】:
以上是关于如何从 Java 8 Date API 中的回历日期中减去回历年份的主要内容,如果未能解决你的问题,请参考以下文章