如何在 js-joda 中比较 LocalDate 和 ZonedDateTime?



我正在寻找一种方法来比较js-jodaLocalDateZonedDateTime的实例,但这些类不兼容。我愿意接受,LocalDate是一个时间和时区设置为零的ZonedDateTime

比较这两个对象的最简单方法是什么?

LocalDate只有一个日期(日、月和年),而ZonedDateTime也有时间(小时、分钟、秒和纳秒)和时区。要比较它们,您必须选择将哪一个转换为另一个的类型。

正如@Dummy的回答已经解释的那样,一种方法是 将ZonedDateTime转换为LocalDate.假设我们有:

var z = ZonedDateTime.now(); // 2017-08-23T13:12:24.856-03:00[America/Sao_Paulo]
var dt = LocalDate.now(); // 2017-08-23

您可以使用equalsisBeforeisAfter的方法检查本地日期(日/月/年)是否相同,在另一个之前或之后

z.toLocalDate().equals(dt); // true
z.toLocalDate().isBefore(dt); // false
z.toLocalDate().isAfter(dt); // false

你也可以使用compareTo,如果第一个日期在第二个日期之前、等于或之后,它可以返回-101

如评论中所述,调用toLocalDate()会丢弃时间和时区信息,只保留日期(日/月/年)。但是,由于LocalDate只有这些字段,因此您不需要其他字段进行比较。


要做相反的事情(将LocalDate转换为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进行比较)。

在这种情况下,z22017-08-23T00:00Z(UTC 时间 2017 年 8月 23 日午夜),而z2017-08-23T13:12:24.856-03:00[America/Sao_Paulo],相当于 UTC 中的2017-08-23T16:12:24.856Z(UTC 时间 2017 年 8 月 2316:12:24.856)。

因此,equals返回false是因为时间和时区不同,isEquals返回false因为它们不代表同一时刻(即使转换为 UTC,也存在不同)。isBefore返回truez2因为实际上在z之前(午夜<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_PauloEurope/Berlin)。 避免使用3个字母的缩写(如CSTPST),因为它们含糊不清且不标准。

您可以通过调用ZoneId.getAvailableZoneIds()来获取可用时区的列表(并选择最适合您系统的时区)。

您也可以将系统的默认时区与ZoneId.systemDefault()一起使用,但这将取决于系统/浏览器,因此最好明确使用特定的时区。

你可以这样做

zonedDateTime.toLocalDate().compareTo(otherLocalDate)

如果zonedDateTimeotherLocalDate之前,则返回-11在之后,0相同

最新更新