Создайте часовой пояс для компании на «рабочий день» в Java - PullRequest
0 голосов
/ 29 апреля 2018

Я работаю в компании, где часть работы в течение дня выполняется в ранние часы следующего дня (то есть, доставка заказов). Теперь для нескольких процессов (в основном, отчетов) мы хотим, чтобы «рабочий день» заканчивался на 04:00 на следующее утро, чтобы мы получали более согласованные значения отчетов в день.

Мы хотим, чтобы это всегда было в 04:00 на следующее утро, и, поскольку на нас влияет летнее время в нашем регионе (Европа - Нидерланды), мы фактически хотим сдвинуть вариант нашего нормального часового пояса на 4 часа со смещением «Европа / Амстердам». (в нашем случае).

Чтобы сделать это простым в использовании для всех приложений в нашей компании, я хотел бы создать небольшую библиотеку, которая просто содержит код, чтобы мои коллеги получили модифицированный экземпляр TimeZone, который делает это. Таким образом, все обычные методы манипуляции с датой и временем могут использоваться вместе с этим специальным часовым поясом.

Я глубоко погрузился в стандартный код Java 8 / Javadoc, связанный с экземплярами TimeZone / ZoneInfo, и в данный момент я не понимаю, какое правильное поле следует изменить в возвращенном экземпляре TimeZone / ZoneInfo.

На данный момент, мое лучшее предположение - установить RawOffset на 4 часа, но я не уверен.

Как правильно достичь моей цели?


Обновление:

Я посмотрел на предложенный LocalTime и, как я и ожидал: ему нужно определение часового пояса, как того, которое следует использовать в качестве «Локального» при преобразовании существующей временной метки (обычно миллисекундных эпох) в «Локальный» часовой пояс.

Глядя на все эти классы, мне кажется, что я буду использовать LocalDate чаще, чем LocalTime.

Фактически код, который я ожидаю получить, выглядит примерно так:

long epoch =  1525033875230L; // Obtained from some dataset
LocalDate localDate = LocalDateTime
  .ofInstant(Instant.ofEpochMilli(epoch), 
             ZoneId.of("Europe/Amsterdam"))
  .toLocalDate();

Где я ожидаю, что мне нужно изменить эту Зону на «правильную».

1 Ответ

0 голосов
/ 30 апреля 2018

Если я правильно понял, то, что вам действительно нужно, это способ преобразования значения в миллисекундах с эпохи в дату таким образом, чтобы дни не менялись на 00:00, но не до 04:00.

static ZoneId zone = ZoneId.of("Europe/Amsterdam");
static LocalTime lastShiftEnds = LocalTime.of(4, 0);

public static LocalDate epochMilliToDate(long epoch) {
    ZonedDateTime dateTime = Instant.ofEpochMilli(epoch)
            .atZone(zone);
    if (dateTime.toLocalTime().isAfter(lastShiftEnds)) { // normal date-time
        return dateTime.toLocalDate();
    } else { // belonging to previous day’s night shift
        return dateTime.toLocalDate().minusDays(1);
    }
}

Используйте, например, так:

    long epoch = 1_525_050_875_230L;
    System.out.println(Instant.ofEpochMilli(epoch));
    LocalDate date = epochMilliToDate(epoch);
    System.out.println(date);

Вывод:

2018-04-30T01:14:35.230Z
2018-04-29

Из печати Instant видно, что время наступило после полуночи (действительно 03: 14: 35.230 в часовом поясе Амстердама). И метод правильно считает, что это время принадлежит 29 апреля, а не 30 апреля.

Возможно, я что-то упустил? С другой стороны, если бы это был я, я бы пошел довольно далеко, чтобы избежать изобретения часового пояса, которого нет в реальной жизни. Такой часовой пояс может сбить с толку ваших коллег.

...