为“工作日”创建公司特定时区'在java中

时间:2018-04-29 09:52:26

标签: java java-8 timezone timezone-offset

我在一家公司工作,一天的部分工作在第二天的早些时候完成(即装运单)。现在有几个流程(主要是报告),我们希望让工作日“工作日”。第二天早上04:00结束,因此我们每天都会获得更一致的报告值。

我们希望第一天早上04:00,因为我们受到夏令时(欧洲 - 荷兰)夏令时的影响,我们实际上需要4小时的正常时区变换'欧洲/阿姆斯特丹' (在我们的例子中)。

为了使它对我们公司的所有应用程序都易于使用,我想创建一个小型库,它只包含代码,以便我的同事获得TimeZone的修改实例。这样,所有正常的时间/日期操作方法都可以与此特殊时区结合使用。

我深入研究了与TimeZone / ZoneInfo实例相关的标准Java 8代码/ Javadoc,此时我不明白在返回的TimeZone / ZoneInfo实例中要更改的正确字段是什么。

此时,我最好的猜测是将RawOffset设置为4小时,但我不确定。

实现目标的正确方法是什么?

更新

我看了一下建议的LocalTime并且正如我所料:它需要一个时区定义,它应该用作" Local"将现有时间戳(通常为纪元毫秒)转换为" Local"时区。

查看所有这些课程似乎比LocalDate更频繁地使用LocalTime

实际上,我希望拥有的代码是这样的:

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

我希望我需要将该区域更改为正确的区域。

1 个答案:

答案 0 :(得分:1)

如果我有正确的话,那么你真正需要的是一种方法,将自纪元以来的毫秒值转换为日期不会改变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)。并且该方法正确地认为此时属于4月29日而不是4月30日。

也许我错过了什么?另一方面,如果那是我的话,我将走很长的路要走,以避免发明现实生活中不存在的时区。这样的时区必然会让你的同事感到困惑。