如何将回历日期转换为公历日期,反之亦然
How to convert from Hijri Date to Georgian Date and vice versa
我正在寻找一种方法来计算例如从现在到特定日期还有多少天,并且我可以使用它来确定我是否处于特定时间段(例如回历 +- 5 天)与否
我现在已经找了 10 多个小时,我找到的最好的东西是“HijrahDate”库“java.time.chrono.HijrahDate”和一个叫“Joda Date”的东西,我用起来有困难。
了解日期和时间在计算机内部表示为与纪元的偏移量:https://en.wikipedia.org/wiki/Epoch_(computing)
在 Java 中,您可以使用 System.currentTimeMillis();
获取此值
你也可以计算日差我减去两个日期数字并应用除法进行单位换算。
long days = (date2 - date1)
/ 1000 // MS
/ 60 // Secs
/ 60 // Mins
/ 24 // Hours
tl;博士
HijrahDate
.from
(
LocalDate.of( 2020 , Month.JANUARY , 23 )
)
.plus
(
Period.ofDays( 5 )
)
.isBefore
(
someOtherDate
)
详情
现代方法使用 java.time classes 内置于 Java 8 和更高版本,以及 Android 26 和之后。对于早期版本,请参阅 ThreeTen-Backport 和 ThreeTenABP 项目。
Joda-Time 项目是 java.time 的前身。两者均由同一个人 Stephen Colebourne 创立和领导。
HijrahChronology
是 java.time 的一部分。 HijrahChronology
遵循 Hijrah 日历系统的规则。回历是支持伊斯兰历的阴历。
HijrahDate
class 表示回历系统中的日期。
搜索 Stack Overflow 以了解更多信息,因为这已被多次介绍。
我不是伊斯兰历或 HijrahChronology
方面的专家,但我相信您可以通过在 [=22] 上调用 from
方法在回历日期和公历(预想)日期之间进行转换=] 和 LocalDate
classes.
LocalDate localDate1 = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
HijrahDate hijrahDate = HijrahDate.from( localDate1 ) ;
……和……
LocalDate localDate2 = LocalDate.from( hijrahDate ) ;
两个日期 classes 都提供了 plus
和 minus
方法,它们采用 Period
对象。
LocalDate later = localDate2.plus( Period.ofDays( 5 ) ) ;
与 isEqual
、isBefore
和 isAfter
比较。
boolean match = localDate1.isEqual( localDate2 ) ;
转储到控制台。
System.out.println( "localDate1.toString(): " + localDate1 ) ;
System.out.println( "hijrahDate.toString(): " + hijrahDate ) ;
System.out.println( "localDate2.toString(): " + localDate2 ) ;
System.out.println( "match: " + localDate1.isEqual( localDate2 ) ) ;
System.out.println( "later.toString(): " + later ) ;
看到这个code run live at IdeOne.com。
localDate1.toString(): 2020-01-23
hijrahDate.toString(): Hijrah-umalqura AH 1441-05-28
localDate2.toString(): 2020-01-23
match: true
later.toString(): 2020-01-28
这是一个完整的例子。这里使用的时间跨度的比较方法是Half-Open,开始是inclusive,结束是exclusive。这种方法通常最适合日期时间处理。这种方法可以让日期范围彼此整齐地相邻,没有间隙或重叠。
LocalDate localDate = LocalDate.of( 2020 , Month.JANUARY , 23 );
HijrahDate hijrahDate = HijrahDate.from( localDate );
// Target range is five days before and after some specific date.
HijrahDate target = HijrahDate.from( LocalDate.of( 2020 , Month.MARCH , 14 ) );
Period period = Period.ofDays( 5 );
LocalDate start = LocalDate.from( target ).minus( period );
LocalDate end = LocalDate.from( target ).plus( period );
// Tip: A shorter way of asking "Is equal to or later" is "Is not before".
boolean withinTargetRange = ( ! hijrahDate.isBefore( start ) ) && hijrahDate.isBefore( end );
转储到控制台。
System.out.println( "localDate = " + localDate );
System.out.println( "hijrahDate = " + hijrahDate );
System.out.println( "target = " + target );
System.out.println( "withinTargetRange = " + withinTargetRange );
localDate = 2020-01-23
hijrahDate = Hijrah-umalqura AH 1441-05-28
target = Hijrah-umalqura AH 1441-07-19
withinTargetRange = false
三十加
如果要完成大部分工作,我建议添加 ThreeTen-Extra library, also founded and led by Stephen Colebourne. The LocalDateRange
class in that library represents a span of time as a pair of LocalDate
objects. This class includes methods such as contains
, abuts
, overlaps
, and more. I do not know how well this library works in Android. If not working well in Android, you may want to pull a copy of the class’s source code into your codebase, provided you can abide by the terms of its BSD-3 licensing。
这里是一个使用 LocalDateRange::contains
的例子。
LocalDate localDate = LocalDate.of( 2020 , Month.JANUARY , 23 );
HijrahDate hijrahDate = HijrahDate.from( localDate );
HijrahDate target = HijrahDate.from( LocalDate.of( 2020 , Month.MARCH , 14 ) );
Period period = Period.ofDays( 5 );
LocalDate start = LocalDate.from( target ).minus( period );
LocalDate end = LocalDate.from( target ).plus( period );
LocalDateRange range = LocalDateRange.of( start , end );
boolean withinTargetRange = range.contains( LocalDate.from( hijrahDate ) );
localDate = 2020-01-23
hijrahDate = Hijrah-umalqura AH 1441-05-28
target = Hijrah-umalqura AH 1441-07-19
range = 2020-03-09/2020-03-19
withinTargetRange = false
您想使用哪种回历?
如果您选择沙特阿拉伯的官方日历,那么基于 java.time.HijrahDate 的解决方案就可以了。但是这个 class 需要在 Android 上至少 API 26 级。示例:
HijrahDate hd1 = HijrahDate.now();
HijrahDate hd2 = HijrahDate.from(LocalDate.of(2020, 5, 1));
long days = ChronoUnit.DAYS.between(hd1, hd2);
还有一些比较方法,例如 isAfter()
或 isBefore()
继承自接口 ChronoLocalDate
和标准的 plus() 方法,以确定您的日期是否在特定时间期间。
java.time
的反向移植:
对于较低的 Android 版本,还有一个名为 ThreetenABP 的向后移植。但要注意它的 HijrahDate
实现不同并且不使用沙特阿拉伯日历的陷阱(因此您必须容忍日期转换的差异)。
关于 Joda-Time:
如果您选择那个(相当过时的)库,那么您应该选择库版本 adapted for android. However, it does not support the calendar of Saudi-Arabia, too, but offers four different other variations. You would need to specify the algorithmic leap year pattern。
ICU4J(嵌入Android):
它的 class IslamicCalendar 提供了一种类似于旧日历 classes java.util.Calendar
的风格,还有包括沙特阿拉伯日历在内的几种变体。所需的最低 API 等级是 24。
Time4A:
这是我自己编写的库(如 adaptation of Time4J for Android). It offers the class HijriCalendar 有多种变体,包括 Joda 变体,但也包括沙特阿拉伯日历(变体 ummalqura)。它提供了所有需要的功能,如日期算法(通过 plus()- 或 minus()- 方法),日期比较(通过 isAfter() 等)。示例:
String variant = HijriCalendar.VARIANT_UMALQURA;
StartOfDay startOfDay = StartOfDay.definedBy(SolarTime.ofMecca().sunset());
HijriCalendar today = HijriCalendar.nowInSystemTime(variant, startOfDay);
HijriCalendar hcal = // gregorian to Hijri conversion
PlainDate.of(2020, 5, 1).transform(HijriCalendar.class, variant);
long days = CalendarDays.between(today, hcal).getAmount();
其他库不支持日落作为一天的开始等功能。 Muharram +- 5days-request 的示例可能如下所示:
CalendarDays tolerance = CalendarDays.of(5);
HijriCalendar htemp = today.with(HijriCalendar.MONTH_OF_YEAR, HijriMonth.MUHARRAM);
HijriCalendar h1 = htemp.with(HijriCalendar.DAY_OF_MONTH.minimized()).minus(tolerance);
HijriCalendar h2 = htemp.with(HijriCalendar.DAY_OF_MONTH.maximized()).plus(tolerance);
boolean inTimePeriod = !(today.isBefore(h1) || today.isAfter(h2));
我正在寻找一种方法来计算例如从现在到特定日期还有多少天,并且我可以使用它来确定我是否处于特定时间段(例如回历 +- 5 天)与否
我现在已经找了 10 多个小时,我找到的最好的东西是“HijrahDate”库“java.time.chrono.HijrahDate”和一个叫“Joda Date”的东西,我用起来有困难。
了解日期和时间在计算机内部表示为与纪元的偏移量:https://en.wikipedia.org/wiki/Epoch_(computing)
在 Java 中,您可以使用 System.currentTimeMillis();
获取此值你也可以计算日差我减去两个日期数字并应用除法进行单位换算。
long days = (date2 - date1)
/ 1000 // MS
/ 60 // Secs
/ 60 // Mins
/ 24 // Hours
tl;博士
HijrahDate
.from
(
LocalDate.of( 2020 , Month.JANUARY , 23 )
)
.plus
(
Period.ofDays( 5 )
)
.isBefore
(
someOtherDate
)
详情
现代方法使用 java.time classes 内置于 Java 8 和更高版本,以及 Android 26 和之后。对于早期版本,请参阅 ThreeTen-Backport 和 ThreeTenABP 项目。
Joda-Time 项目是 java.time 的前身。两者均由同一个人 Stephen Colebourne 创立和领导。
HijrahChronology
是 java.time 的一部分。 HijrahChronology
遵循 Hijrah 日历系统的规则。回历是支持伊斯兰历的阴历。
HijrahDate
class 表示回历系统中的日期。
搜索 Stack Overflow 以了解更多信息,因为这已被多次介绍。
我不是伊斯兰历或 HijrahChronology
方面的专家,但我相信您可以通过在 [=22] 上调用 from
方法在回历日期和公历(预想)日期之间进行转换=] 和 LocalDate
classes.
LocalDate localDate1 = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
HijrahDate hijrahDate = HijrahDate.from( localDate1 ) ;
……和……
LocalDate localDate2 = LocalDate.from( hijrahDate ) ;
两个日期 classes 都提供了 plus
和 minus
方法,它们采用 Period
对象。
LocalDate later = localDate2.plus( Period.ofDays( 5 ) ) ;
与 isEqual
、isBefore
和 isAfter
比较。
boolean match = localDate1.isEqual( localDate2 ) ;
转储到控制台。
System.out.println( "localDate1.toString(): " + localDate1 ) ;
System.out.println( "hijrahDate.toString(): " + hijrahDate ) ;
System.out.println( "localDate2.toString(): " + localDate2 ) ;
System.out.println( "match: " + localDate1.isEqual( localDate2 ) ) ;
System.out.println( "later.toString(): " + later ) ;
看到这个code run live at IdeOne.com。
localDate1.toString(): 2020-01-23
hijrahDate.toString(): Hijrah-umalqura AH 1441-05-28
localDate2.toString(): 2020-01-23
match: true
later.toString(): 2020-01-28
这是一个完整的例子。这里使用的时间跨度的比较方法是Half-Open,开始是inclusive,结束是exclusive。这种方法通常最适合日期时间处理。这种方法可以让日期范围彼此整齐地相邻,没有间隙或重叠。
LocalDate localDate = LocalDate.of( 2020 , Month.JANUARY , 23 );
HijrahDate hijrahDate = HijrahDate.from( localDate );
// Target range is five days before and after some specific date.
HijrahDate target = HijrahDate.from( LocalDate.of( 2020 , Month.MARCH , 14 ) );
Period period = Period.ofDays( 5 );
LocalDate start = LocalDate.from( target ).minus( period );
LocalDate end = LocalDate.from( target ).plus( period );
// Tip: A shorter way of asking "Is equal to or later" is "Is not before".
boolean withinTargetRange = ( ! hijrahDate.isBefore( start ) ) && hijrahDate.isBefore( end );
转储到控制台。
System.out.println( "localDate = " + localDate );
System.out.println( "hijrahDate = " + hijrahDate );
System.out.println( "target = " + target );
System.out.println( "withinTargetRange = " + withinTargetRange );
localDate = 2020-01-23
hijrahDate = Hijrah-umalqura AH 1441-05-28
target = Hijrah-umalqura AH 1441-07-19
withinTargetRange = false
三十加
如果要完成大部分工作,我建议添加 ThreeTen-Extra library, also founded and led by Stephen Colebourne. The LocalDateRange
class in that library represents a span of time as a pair of LocalDate
objects. This class includes methods such as contains
, abuts
, overlaps
, and more. I do not know how well this library works in Android. If not working well in Android, you may want to pull a copy of the class’s source code into your codebase, provided you can abide by the terms of its BSD-3 licensing。
这里是一个使用 LocalDateRange::contains
的例子。
LocalDate localDate = LocalDate.of( 2020 , Month.JANUARY , 23 );
HijrahDate hijrahDate = HijrahDate.from( localDate );
HijrahDate target = HijrahDate.from( LocalDate.of( 2020 , Month.MARCH , 14 ) );
Period period = Period.ofDays( 5 );
LocalDate start = LocalDate.from( target ).minus( period );
LocalDate end = LocalDate.from( target ).plus( period );
LocalDateRange range = LocalDateRange.of( start , end );
boolean withinTargetRange = range.contains( LocalDate.from( hijrahDate ) );
localDate = 2020-01-23
hijrahDate = Hijrah-umalqura AH 1441-05-28
target = Hijrah-umalqura AH 1441-07-19
range = 2020-03-09/2020-03-19
withinTargetRange = false
您想使用哪种回历?
如果您选择沙特阿拉伯的官方日历,那么基于 java.time.HijrahDate 的解决方案就可以了。但是这个 class 需要在 Android 上至少 API 26 级。示例:
HijrahDate hd1 = HijrahDate.now();
HijrahDate hd2 = HijrahDate.from(LocalDate.of(2020, 5, 1));
long days = ChronoUnit.DAYS.between(hd1, hd2);
还有一些比较方法,例如 isAfter()
或 isBefore()
继承自接口 ChronoLocalDate
和标准的 plus() 方法,以确定您的日期是否在特定时间期间。
java.time
的反向移植:
对于较低的 Android 版本,还有一个名为 ThreetenABP 的向后移植。但要注意它的 HijrahDate
实现不同并且不使用沙特阿拉伯日历的陷阱(因此您必须容忍日期转换的差异)。
关于 Joda-Time:
如果您选择那个(相当过时的)库,那么您应该选择库版本 adapted for android. However, it does not support the calendar of Saudi-Arabia, too, but offers four different other variations. You would need to specify the algorithmic leap year pattern。
ICU4J(嵌入Android):
它的 class IslamicCalendar 提供了一种类似于旧日历 classes java.util.Calendar
的风格,还有包括沙特阿拉伯日历在内的几种变体。所需的最低 API 等级是 24。
Time4A:
这是我自己编写的库(如 adaptation of Time4J for Android). It offers the class HijriCalendar 有多种变体,包括 Joda 变体,但也包括沙特阿拉伯日历(变体 ummalqura)。它提供了所有需要的功能,如日期算法(通过 plus()- 或 minus()- 方法),日期比较(通过 isAfter() 等)。示例:
String variant = HijriCalendar.VARIANT_UMALQURA;
StartOfDay startOfDay = StartOfDay.definedBy(SolarTime.ofMecca().sunset());
HijriCalendar today = HijriCalendar.nowInSystemTime(variant, startOfDay);
HijriCalendar hcal = // gregorian to Hijri conversion
PlainDate.of(2020, 5, 1).transform(HijriCalendar.class, variant);
long days = CalendarDays.between(today, hcal).getAmount();
其他库不支持日落作为一天的开始等功能。 Muharram +- 5days-request 的示例可能如下所示:
CalendarDays tolerance = CalendarDays.of(5);
HijriCalendar htemp = today.with(HijriCalendar.MONTH_OF_YEAR, HijriMonth.MUHARRAM);
HijriCalendar h1 = htemp.with(HijriCalendar.DAY_OF_MONTH.minimized()).minus(tolerance);
HijriCalendar h2 = htemp.with(HijriCalendar.DAY_OF_MONTH.maximized()).plus(tolerance);
boolean inTimePeriod = !(today.isBefore(h1) || today.isAfter(h2));