我正在寻找一种方法来比较LocalDate
和ZonedDateTime
in 的实例js-joda
,但这些类不兼容。我愿意接受,即LocalDate
时间ZonedDateTime
和时区设置为零。
比较这两个对象的最简单方法是什么?
我正在寻找一种方法来比较LocalDate
和ZonedDateTime
in 的实例js-joda
,但这些类不兼容。我愿意接受,即LocalDate
时间ZonedDateTime
和时区设置为零。
比较这两个对象的最简单方法是什么?
ALocalDate
只有一个日期(日、月和年),而AZonedDateTime
也有时间(小时、分钟、秒和纳秒)和时区。要比较它们,您必须选择将哪一个转换为另一个类型。
正如@Dummy's answer已经解释的那样,一种方法是将 转换ZonedDateTime
为LocalDate
. 假设我们有:
var z = ZonedDateTime.now(); // 2017-08-23T13:12:24.856-03:00[America/Sao_Paulo]
var dt = LocalDate.now(); // 2017-08-23
您可以使用方法equals
,isBefore
或isAfter
检查本地日期(日/月/年)是否相同,在另一个之前或之后
z.toLocalDate().equals(dt); // true
z.toLocalDate().isBefore(dt); // false
z.toLocalDate().isAfter(dt); // false
您也可以使用compareTo
, 可以返回-1
,0
或者1
如果第一个日期在第二个日期之前、等于或之后。
正如评论中所说,调用toLocalDate()
会丢弃时间和时区信息,只保留日期(日/月/年)。但是由于 LocalDate
只有这些字段,您不需要其他人进行比较。
要反其道而行之(将 转换LocalDate
为 a ZonedDateTime
),您必须做出一些假设。根据您所在的时区,同一日期可以代表不同的时刻(现在在圣保罗是 8 月 23日,但在东京是 8 月 24日- 您选择的时区可能会影响最终结果)。
您还需要定义该日期的时间(小时/分钟/秒/纳秒)。您告诉过您可以假设LocalDate 是 ZonedDateTime ,时间和时区设置为零。这意味着时间将是午夜 (00:00),时区将是 UTC(偏移量为零):
// consider LocalDate = ZonedDateTime with time and timezone set to zero (midnight in UTC)
var z2 = dt.atStartOfDay(ZoneOffset.UTC); // 2017-08-23T00:00Z
然后你可以比较:
z2.equals(z); // false: check if all fields are the same (date/time/timezone)
z2.isEqual(z); // false: check if both represent the same instant (even if timezones are different)
z2.isBefore(z); // true
z2.isAfter(z); // false
z2.compareTo(z); // -1
请注意,equals
检查所有字段是否相同(日期、时间和时区),而所有其他方法比较等价的Instant
(即使时区不同,Instant
也使用对应的进行比较)。
在这种情况下,z2
is 2017-08-23T00:00Z
(UTC 时间 2017 年 8 月 23日午夜),而z
is 2017-08-23T13:12:24.856-03:00[America/Sao_Paulo]
,在 UTC 中等效于2017-08-23T16:12:24.856Z
(UTC 时间 2017 年 8 月 23日16:12:24.856)。
因此,equals
返回false
是因为时间和时区不同,isEquals
返回false
是因为它们不代表同一时刻(即使转换为 UTC,它们也是不同的)。isBefore
返回true
,因为z2
实际上是在z
(midnight < 16:12) 之前,依此类推。
如果要使用另一个时区而不是 UTC,则必须使用js-joda-timezone和ZoneId
类:
// get this date at midnight in London timezone
dt.atStartOfDay(ZoneId.of("Europe/London"));
API 使用IANA 时区名称(始终采用格式Region/City
,例如America/Sao_Paulo
或Europe/Berlin
)。避免使用 3 个字母的缩写(如CST
or PST
),因为它们模棱两可且不标准。
您可以通过调用获取可用时区列表(并选择最适合您系统的时区)ZoneId.getAvailableZoneIds()
。
您也可以将系统的默认时区与 一起使用ZoneId.systemDefault()
,但这将取决于系统/浏览器,因此最好明确使用特定的时区。
你可以这样做
zonedDateTime.toLocalDate().compareTo(otherLocalDate)
哪个返回-1
if zonedDateTime
is before otherLocalDate
, 1
is after,0
是一样的