我在一家公司工作,一天的部分工作在第二天的早些时候完成(即装运单)。现在有几个流程(主要是报告),我们希望让工作日“工作日”。第二天早上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();
我希望我需要将该区域更改为正确的区域。
答案 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日。
也许我错过了什么?另一方面,如果那是我的话,我将走很长的路要走,以避免发明现实生活中不存在的时区。这样的时区必然会让你的同事感到困惑。