在 Time4j(波斯历)中定义日期范围
Define a date range in Time4j (Persian calendar)
我想像这样定义一个日期范围:
- 从
"1396/8/9"
开始
- 结束到
"1396/9/2"
并获取这两个日期之间的天数。
通过网络搜索,在Time4j中找到了一个DateInterval
函数
是否可以使用这种方法来定义波斯历中的可选日期范围?如果是,我该如何使用此方法来达到我的目的?
使用转化
class DateInterval 专为 ISO-8601 设计,仅适用于公历。因此,您将自己负责公历类型 PlainDate
和目标类型 PersianCalendar
:
之间的转换
DateInterval interval =
DateInterval.between(
PersianCalendar.of(1396, 8, 9).transform(PlainDate.axis()),
PersianCalendar.of(1396, 9, 2)).transform(PlainDate.axis());
对于反向转换:
PersianCalendar start = interval.getStartAsCalendarDate().transform(PersianCalendar.axis());
当然,你也可以每天循环你的间隔:
interval
.streamDaily()
.map(d -> d.transform(PersianCalendar.axis()))
.forEach(System.out::println);
旁注:
DateInterval
默认关闭(大多数与业务日期相关的应用程序都需要),但可以通过调用 interval.withOpenEnd()
.
配置为半开
选择:
甚至还有一种方法可以直接在区间中存储PersianCalendar
的实例,即SimpleInterval(注意:在v4.31之前总是半开!)。示例:
SimpleInterval<PersianCalendar> pInterval =
SimpleInterval.onTimeLine(PersianCalendar.axis()).between(
PersianCalendar.of(1396, 8, 9),
PersianCalendar.of(1396, 9, 2).plus(CalendarDays.ONE)
);
通过普通的 for 循环进行每日循环:
for (
PersianCalendar pcal = pInterval.getStart().getTemporal();
pcal.isBefore(pInterval.getEnd().getTemporal();
pcal = pcal.plus(CalendarDays.ONE)
) {
System.out.println(pcal);
}
但是,我真的不建议使用 SimpleInterval
,因为 a) 它的功能比 DateInterval
少,b) 主要是为 java.util.Date
等非日历类型设计的(因为这样的间隔总是半开的,而日历间隔在大多数业务应用程序中最好关闭)。
可选范围
关于你的术语"optional date range",我不太清楚意思。你能澄清一下吗?也许您在谈论无限或半无限区间边界。这个有可能。只需构建您的间隔而不是 between(...)
,而是 since(...)
或 until(...)
。但这会影响您的循环代码(您不能从无穷大循环或直到无穷大。)。
更新 (2017-10-21)
从 v4.31 版开始,class SimpleInterval
得到增强,可以更好地处理日历类型,即始终关闭而不是半开(但即时 -当然,像间隔仍然是半开的)。为此引入了一些新方法,例如on(TimeAxis)。 link 后面的 javadoc 显示了一个示例:
PersianCalendar start = PersianCalendar.of(1392, PersianMonth.ESFAND, 27);
PersianCalendar end = PersianCalendar.of(1393, PersianMonth.FARVARDIN, 6);
SimpleInterval<PersianCalendar> i1 =
SimpleInterval.on(PersianCalendar.axis()).between(start, end);
SimpleInterval<PersianCalendar> i2 =
SimpleInterval.on(PersianCalendar.axis()).between(
end.minus(CalendarDays.ONE),
end.plus(CalendarDays.ONE));
System.out.println(
interval.findIntersection(
SimpleInterval.on(PersianCalendar.axis()).between(
end.minus(CalendarDays.ONE), end.plus(CalendarDays.ONE))).get());
// [AP-1393-01-05/AP-1393-01-06]
这样的日历间隔可以照常在 IntervalCollection
或 IntervalTree
内处理。
我想像这样定义一个日期范围:
- 从
"1396/8/9"
开始 - 结束到
"1396/9/2"
并获取这两个日期之间的天数。
通过网络搜索,在Time4j中找到了一个DateInterval
函数
是否可以使用这种方法来定义波斯历中的可选日期范围?如果是,我该如何使用此方法来达到我的目的?
使用转化
class DateInterval 专为 ISO-8601 设计,仅适用于公历。因此,您将自己负责公历类型 PlainDate
和目标类型 PersianCalendar
:
DateInterval interval =
DateInterval.between(
PersianCalendar.of(1396, 8, 9).transform(PlainDate.axis()),
PersianCalendar.of(1396, 9, 2)).transform(PlainDate.axis());
对于反向转换:
PersianCalendar start = interval.getStartAsCalendarDate().transform(PersianCalendar.axis());
当然,你也可以每天循环你的间隔:
interval
.streamDaily()
.map(d -> d.transform(PersianCalendar.axis()))
.forEach(System.out::println);
旁注:
DateInterval
默认关闭(大多数与业务日期相关的应用程序都需要),但可以通过调用 interval.withOpenEnd()
.
选择:
甚至还有一种方法可以直接在区间中存储PersianCalendar
的实例,即SimpleInterval(注意:在v4.31之前总是半开!)。示例:
SimpleInterval<PersianCalendar> pInterval =
SimpleInterval.onTimeLine(PersianCalendar.axis()).between(
PersianCalendar.of(1396, 8, 9),
PersianCalendar.of(1396, 9, 2).plus(CalendarDays.ONE)
);
通过普通的 for 循环进行每日循环:
for (
PersianCalendar pcal = pInterval.getStart().getTemporal();
pcal.isBefore(pInterval.getEnd().getTemporal();
pcal = pcal.plus(CalendarDays.ONE)
) {
System.out.println(pcal);
}
但是,我真的不建议使用 SimpleInterval
,因为 a) 它的功能比 DateInterval
少,b) 主要是为 java.util.Date
等非日历类型设计的(因为这样的间隔总是半开的,而日历间隔在大多数业务应用程序中最好关闭)。
可选范围
关于你的术语"optional date range",我不太清楚意思。你能澄清一下吗?也许您在谈论无限或半无限区间边界。这个有可能。只需构建您的间隔而不是 between(...)
,而是 since(...)
或 until(...)
。但这会影响您的循环代码(您不能从无穷大循环或直到无穷大。)。
更新 (2017-10-21)
从 v4.31 版开始,class SimpleInterval
得到增强,可以更好地处理日历类型,即始终关闭而不是半开(但即时 -当然,像间隔仍然是半开的)。为此引入了一些新方法,例如on(TimeAxis)。 link 后面的 javadoc 显示了一个示例:
PersianCalendar start = PersianCalendar.of(1392, PersianMonth.ESFAND, 27);
PersianCalendar end = PersianCalendar.of(1393, PersianMonth.FARVARDIN, 6);
SimpleInterval<PersianCalendar> i1 =
SimpleInterval.on(PersianCalendar.axis()).between(start, end);
SimpleInterval<PersianCalendar> i2 =
SimpleInterval.on(PersianCalendar.axis()).between(
end.minus(CalendarDays.ONE),
end.plus(CalendarDays.ONE));
System.out.println(
interval.findIntersection(
SimpleInterval.on(PersianCalendar.axis()).between(
end.minus(CalendarDays.ONE), end.plus(CalendarDays.ONE))).get());
// [AP-1393-01-05/AP-1393-01-06]
这样的日历间隔可以照常在 IntervalCollection
或 IntervalTree
内处理。