如何在Java中的时间与日期之间进行间隔

时间:2018-06-21 02:45:23

标签: java date java-stream

我需要指定时间内的日期。

示例1: 让我当前的时间实例:15-06-2018 08:00 AM 如果我在24小时前输入,我需要的日期为14-06-2018和15-06-2018,因为距当前实例24小时也意味着昨天的日期。

例2: 让我当前的时间实例:15-06-2018 08:00 AM 如果我在7小时前给出输入,则我需要日期为15-06-2018,因为距当前实例7小时意味着只有今天。

我尝试使用下面的代码,但未给出预期的结果。请提出是否有更好的方法可以做到这一点:

pre = LocalDateTime.now().minusMinutes(duration);
numOfDaysBetween = ChronoUnit.DAYS.between(pre, 
LocalDateTime.now().plusDays(1));
System.out.println(numOfDaysBetween);
if (numOfDaysBetween > 0) {
            dateList = IntStream.iterate(0, i -> i + 1).limit(numOfDaysBetween).mapToObj(i -> pre.plusDays(i)).collect(Collectors.toList());
            for (LocalDateTime d : dateList) {
                System.out.println(String.format("%04d", d.getYear()) + "." + String.format("%02d", d.getMonthValue()) + "." + String.format("%02d", d.getDayOfMonth()));
            }
        }

2 个答案:

答案 0 :(得分:1)

LocalDateTime now = LocalDateTime.parse("2018-06-21T08:40:00.00Z", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
LocalDateTime then = now.minusHours(7);
LocalDate start;
LocalDate target;
int delta = 1;
if (then.isBefore(now)) {
    start = then.toLocalDate();
    target = now.toLocalDate();
    delta = 1;
} else {
    start = now.toLocalDate();
    target = then.toLocalDate();
    delta = -1;
}
target = target.plusDays(1);
while (start.isBefore(target)) {
    System.out.println(start);
    start = start.plusDays(delta);
}

输入/输出结果...

+-------+------------+
| Input |   Output   |
+-------+------------+
|    24 | 2018-06-20 |
|       | 2018-06-21 |
+-------+------------+
|     9 | 2018-06-20 |
|       | 2018-06-21 |
+-------+------------+
|     7 | 2018-06-21 |
+-------+------------+

尽管,如果要避免日光节约的可能性,您可以考虑使用更多类似...

Instant now = Instant.parse("2018-06-21T08:40:00.00Z");
Instant then = now.minus(9, ChronoUnit.HOURS);
Instant start;
Instant target;
int delta = 1;
if (then.isBefore(now)) {
    start = then;
    target = now;
} else {
    start = now;
    target = then;
    delta = -1;
}
if (!target.truncatedTo(ChronoUnit.DAYS).equals(start.truncatedTo(ChronoUnit.DAYS))) {
    target = target.plus(1, ChronoUnit.DAYS);
}
while (start.isBefore(target)) {
    System.out.println(start);
    start = start.plus(delta, ChronoUnit.DAYS);
}

输入/输出结果

+-------+----------------------+
| Input |        Output        |
+-------+----------------------+
|    24 | 2018-06-20T08:40:00Z |
|       | 2018-06-21T08:40:00Z |
+-------+----------------------+
|     9 | 2018-06-20T23:40:00Z |
|       | 2018-06-21T23:40:00Z |
+-------+----------------------+
|     7 | 2018-06-21T01:40:00Z |
+-------+----------------------+

答案 1 :(得分:1)

这就是LocalDate.datesUntil method introduced in Java 9的作用。

    ZoneId zone = ZoneId.of("Australia/Sydney");
    ZonedDateTime now = ZonedDateTime.now(zone);
    Duration duration = Duration.ofHours(16);
    LocalDate preDate = now.minus(duration).toLocalDate();
    LocalDate endExclusive = now.toLocalDate().plusDays(1);
    List<LocalDate> dateList 
            = preDate.datesUntil(endExclusive).collect(Collectors.toList());
    System.out.println(dateList);

现在正在跑步(悉尼14:30),我得到了这个结果:

  

[2018-06-20,2018-06-21]

其他技巧:使用ZonedDateTime查找起点。在某些情况下,例如在夏令时(DST)前后,LocalDateTime不会给您正确的结果。

并显式指定时区。即使您只指定ZoneId.systemDefault(),也是在告诉读者-以及您自己-您已经有意识地选择了使用的时区。

您的代码出了什么问题?

从现在到7小时之前有0天。还是23小时前,就此事。 ChronoUnit.DAYS.between仅占整天。为了获得正确的日期数,您需要在计数之前转换为LocalDate