如何在没有时间的情况下将公历转换为伊斯兰(Hijri)日期?

时间:2019-04-21 14:05:45

标签: java datetime localdate hijri

请参见SO 15728744SO 51058875

以下内容如何正确:

LocalDate gregorianDate = LocalDate.parse(gregorianString, dateFormatter);
HijrahDate islamicDate = HijrahDate.from(gregorianDate);

我以为回教日是在日落而不是在午夜结束的,所以应该使用gregorianDateTime。

2 个答案:

答案 0 :(得分:2)

您是对的,回历日历从上一个西方日的日落开始。您还可以说标准Java不支持它。

为什么?

我搜索了旧的Threeten存档,但一无所获。但是,java.time-API的主要开发者和架构师曾经在documentation of the ancestor Joda-Time的以下句子中指出:

  

此实现将一天定义为从午夜到午夜,与   按照ISO年表。正确的开始时间是日落时   前一天,但是这不能轻易建模并且已经   忽略。

我的推测是:同样的动机也是为什么java.time不考虑一天中与伊斯兰日历之间的转换的原因。主要由于需要天文计算而难以实施。

如何处理这种缺陷?

在标准Java范围内,建议用户尽可能忽略一天中的时间。因此,请记住,此类转换是无时间的抽象。当然,如果要确定当前日期(间接涉及一天中的时间和民用时区),那么这种转换或多或少都是错误的!

如果您不想在开始时忽略日落...

...然后您可以使用我的库Time4J(而且我不知道还有其他可以在日落时开始处理日落的库)。请注意类HijriCalendar的文档。 generic conversion从瞬间/即时到回历日期的示例:

// the geographic location
SolarTime meccaTime = SolarTime.ofLocation(21.4225, 39.826111); 
// or even simple: meccaTime = SolarTime.ofMecca()

// the moment to be converted
Moment now = SystemClock.currentTime();
// alternative using an explicit gregorian date:
//   now = PlainDate.of(2019, 5, 26).atTime(18, 45).inStdTimezone();
// alternative using modern Java: 
//   now = Moment.from(Instant.now());
// alternative using outdated old API: 
//   java.util.Date instant = new java.util.Date();
//   now = TemporalType.JAVA_UTIL_DATE.translate(instant);

// the conversion
HijriCalendar hcal = now.toGeneralTimestamp(
  HijriCalendar.family(),
  HijriCalendar.VARIANT_UMALQURA, // attention: there is no single islamic calendar
  Timezone.ofSystem().getID(), // or use something like: ()-> "Europe/London"
  StartOfDay.definedBy(meccaTime.sunset()));

Time4J还包含一种格式引擎,该引擎能够以多种方式解析公历日期或回历日历日期时间。在基于ChronoFormatter的格式化和解析过程中,也可以考虑日落的开始时间。

还支持从回历日历日期到某一时刻的反向转换。示例:

HijriCalendar hcal = ...;
Moment m = 
  hcal.atTime(18, 45).in(Timezone.ofSystem(), StartOfDay.definedBy(meccaTime.sunset()));

答案 1 :(得分:0)

Java文档中提到LocalDate类不考虑时间。

引用:https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html

  

此类不存储或表示时间或   时区。相反,它是日期的描述,用于   生日。

考虑使用LocalDateTime满足您的要求。