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

时间:2017-06-24 09:30:55

标签: javascript localdate zoneddatetime datetime-comparison js-joda

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

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

2 个答案:

答案 0 :(得分:1)

你可以这样做

zonedDateTime.toLocalDate().compareTo(otherLocalDate)

如果-1zonedDateTime之前,otherLocalDate之后,1是相同的,那么会返回0

答案 1 :(得分:1)

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

正如@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

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

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

您还可以使用compareTo,如果第一个日期在之前,等于或之后,则可以返回-101

作为told in the comments,调用toLocalDate()会丢弃时间和时区信息,只保留日期(日/月/年)。但由于LocalDate只有这些字段,因此您无需其他字段进行比较。

要做相反的事情(将LocalDate转换为ZonedDateTime),您必须做出一些假设。根据您所在的时区,相同的日期可能代表不同的时刻(现在是圣保罗的8月23日 th ,但东京是8月24日 th - 时区你选择可能会影响最终结果。)

您还需要定义此日期时间(小时/分钟/秒/纳秒)。你告诉过你可以假设 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(即使时区不同,相应的{{3}用于进行比较)。

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

因此,equals会返回false,因为时区和时区不同而isEquals会返回false,因为它们不代表同一时刻(即使转换为UTC时也是如此) ,他们是不同的)。 isBefore返回true,因为z2实际上在z之前(午夜< 16:12),依此类推。

如果您想使用其他时区而不是UTC,则必须使用InstantZoneId类:

// get this date at midnight in London timezone
dt.atStartOfDay(ZoneId.of("Europe/London"));

API使用js-joda-timezone(始终采用Region/City格式,如America/Sao_PauloEurope/Berlin。 避免使用3个字母的缩写(例如CSTPST),因为它们是IANA timezones names

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

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