我正在寻找一种方法来比较LocalDate
中ZonedDateTime
和js-joda
的实例,但这些类不兼容。我愿意接受,LocalDate
是ZonedDateTime
,时间和时区设置为零。
比较这两个对象最简单的方法是什么?
答案 0 :(得分:1)
你可以这样做
zonedDateTime.toLocalDate().compareTo(otherLocalDate)
如果-1
在zonedDateTime
之前,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
您可以使用方法equals
,isBefore
或isAfter
检查本地日期(日/月/年)是否相同,在其他之前或之后
z.toLocalDate().equals(dt); // true
z.toLocalDate().isBefore(dt); // false
z.toLocalDate().isAfter(dt); // false
您还可以使用compareTo
,如果第一个日期在之前,等于或之后,则可以返回-1
,0
或1
。
作为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}用于进行比较)。
在这种情况下,z2
为2017-08-23T00:00Z
(2017年8月23日 th ,UTC时间午夜),而z
为2017-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,则必须使用Instant
和ZoneId
类:
// get this date at midnight in London timezone
dt.atStartOfDay(ZoneId.of("Europe/London"));
API使用js-joda-timezone(始终采用Region/City
格式,如America/Sao_Paulo
或Europe/Berlin
。
避免使用3个字母的缩写(例如CST
或PST
),因为它们是IANA timezones names。
您可以致电ZoneId.getAvailableZoneIds()
获取可用时区列表(并选择最适合您系统的时区)。
您也可以将系统的默认时区与ZoneId.systemDefault()
一起使用,但这将取决于系统/浏览器,因此最好明确使用特定的时区。