Учитывая форматированный диапазон DateTime, разделяйте и печатайте каждый час вне этого диапазона - PullRequest
0 голосов
/ 08 мая 2018

Цель алгоритма - разбить интервал времени на отдельные даты.

У меня есть переменная: TimeInterval = 2018-05-03T04:00Z/2018-05-03T06:00Z Какой диапазон 2 часа.

String[] All_Time = TimeInterval.split("/");
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm'Z'");
LocalDateTime datetimestart = LocalDateTime.parse(All_Time[0], dateFormat);
LocalDateTime datetimeend = LocalDateTime.parse(All_Time[1], dateFormat);
do {
    id = datetimestart.toString();
    System.out.println(id+"/"+datetimestart.plusHours(1).toString());
    datetimestart = datetimestart.plusHours(1);
  } while (datetimestart.plusHours(1).equals(datetimeend));
System.out.println("Time End: "+datetimeend);

Это печатает:

2018-05-03T04:00/2018-05-03T05:00
2018-05-03T05:00/2018-05-03T06:00
Time End: 2018-05-03T06:00

Это именно то, что я хочу (хотя я замечаю, что Z отсутствует ...).

Но, когда интервал времени составляет 24 часа (и здесь я должен также проверить день 23 и 25 часов), цикл прерывается, и с учетом этого TimeInterval = 2018-05-03T04:00Z/2018-05-04T04:00Z Выход:

2018-05-03T08:00/2018-05-03T09:00
Time End: 2018-05-04T04:00

Я знаю, что это проблема с plusHours(1), который не может добавить +1 к дню, и, возможно, то же самое происходит при переходе с 31-го (28, 29, 30-го числа месяца) на 1-е число в следующем месяце -> ... и то же самое в течение года.

Есть ли решение для этого?

UPDATE

for (int inc=0; inc<=24; inc++){
  System.out.println("Hour: "+datetimestart.plusHours(inc));
}

Печать:

Hour: 2018-05-03T08:00
Hour: 2018-05-03T09:00
Hour: 2018-05-03T10:00
Hour: 2018-05-03T11:00
Hour: 2018-05-03T12:00
Hour: 2018-05-03T13:00
Hour: 2018-05-03T14:00
Hour: 2018-05-03T15:00
Hour: 2018-05-03T16:00
Hour: 2018-05-03T17:00
Hour: 2018-05-03T18:00
Hour: 2018-05-03T19:00
Hour: 2018-05-03T20:00
Hour: 2018-05-03T21:00
Hour: 2018-05-03T22:00
Hour: 2018-05-03T23:00
Hour: 2018-05-04T00:00
Hour: 2018-05-04T01:00
Hour: 2018-05-04T02:00
Hour: 2018-05-04T03:00
Hour: 2018-05-04T04:00
Hour: 2018-05-04T05:00
Hour: 2018-05-04T06:00
Hour: 2018-05-04T07:00
Hour: 2018-05-04T08:00

Для меня это означает, что есть хорошие шансы, что цикл do-while может быть не самым лучшим, я не уверен, почему.

1 Ответ

0 голосов
/ 08 мая 2018
    String timeInterval = "2018-05-03T08:00Z/2018-05-04T04:00Z";
    String[] allTime = timeInterval.split("/");
    if (allTime.length != 2) {
        throw new IllegalStateException("Wrong number of datetimes, should be 2");
    }
    OffsetDateTime dateTimeStart = OffsetDateTime.parse(allTime[0]);
    OffsetDateTime dateTimeEnd = OffsetDateTime.parse(allTime[1]);
    OffsetDateTime current = dateTimeStart;
    while (current.isBefore(dateTimeEnd)) {
        OffsetDateTime next = current.plusHours(1);
        System.out.println("" + current + '/' + next);
        current = next;
    }
    System.out.println("Time End: " + dateTimeEnd);

Вывод (сокращенно в середине):

2018-05-03T08:00Z/2018-05-03T09:00Z
2018-05-03T09:00Z/2018-05-03T10:00Z
2018-05-03T10:00Z/2018-05-03T11:00Z
…
2018-05-03T22:00Z/2018-05-03T23:00Z
2018-05-03T23:00Z/2018-05-04T00:00Z
2018-05-04T00:00Z/2018-05-04T01:00Z
2018-05-04T01:00Z/2018-05-04T02:00Z
2018-05-04T02:00Z/2018-05-04T03:00Z
2018-05-04T03:00Z/2018-05-04T04:00Z
Time End: 2018-05-04T04:00Z

Ваше while состояние было неверным. Вы использовали equals, который гарантировал, что вы прошли второй цикл только в том случае, если конец второго часа совпадает с вашим временем окончания. И никогда в третий раз. Вместо этого используйте isBefore как в моем коде. Другой вариант - ! datetimestart.isEqual(datetimeend) (восклицательный знак означает «нет»). Я предполагаю, что интервал всегда равен целому числу часов, и что начало и конец имеют одинаковое смещение UTC (Z означает смещение ноль). Иначе это будет немного сложнее.

Другие примечания:

  • Используйте соглашения об именах (по крайней мере, когда вы делитесь своим кодом в Stack Overflow и в других местах). Имена переменных начинаются со строчной буквы и не содержат подчеркивания.
  • Чтобы сохранить Z, используйте OffsetDateTime, а не LocalDateTime. Поскольку ваши строки времени начала и окончания представлены в стандартном формате ISO 8601, вам не нужно DateTimeFormatter в вашем случае.
...