Java 为'创建特定于公司的时区;工作日';在爪哇

Java 为'创建特定于公司的时区;工作日';在爪哇,java,java-8,timezone,timezone-offset,Java,Java 8,Timezone,Timezone Offset,我在一家公司工作,一天的部分工作在第二天的早些时候完成(即发货订单)。现在,对于几个流程(主要是报告),我们希望让“工作日”在第二天早上04:00结束,这样我们每天的报告值更加一致 我们希望这总是在第二天早上4:00,由于我们所在地区(欧洲-荷兰)受到夏令时的影响,我们实际上希望我们的正常时区“欧洲/阿姆斯特丹”有一个4小时轮班的变体(在我们的例子中) 为了使其易于用于我们公司的所有应用程序,我想创建一个小的库,其中只包含代码,以便让我的同事获得一个修改后的时区实例。这样,所有正常的时间/日期操

我在一家公司工作,一天的部分工作在第二天的早些时候完成(即发货订单)。现在,对于几个流程(主要是报告),我们希望让“工作日”在第二天早上
04:00
结束,这样我们每天的报告值更加一致

我们希望这总是在第二天早上4:00,由于我们所在地区(欧洲-荷兰)受到夏令时的影响,我们实际上希望我们的正常时区“欧洲/阿姆斯特丹”有一个4小时轮班的变体(在我们的例子中)

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

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

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

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


更新:

我看了一下建议的
LocalTime
,正如我所料:它需要一个时区定义,当将现有时间戳(通常是历元毫秒)转换为“本地”时区时,它应该使用“本地”定义

查看所有这些类,我似乎会比使用
LocalTime
更频繁地使用
LocalDate

实际上,我期望的代码是这样的:

long epoch =  1525033875230L; // Obtained from some dataset
LocalDate localDate = LocalDateTime
  .ofInstant(Instant.ofEpochMilli(epoch), 
             ZoneId.of("Europe/Amsterdam"))
  .toLocalDate();
    long epoch = 1_525_050_875_230L;
    System.out.println(Instant.ofEpochMilli(epoch));
    LocalDate date = epochMilliToDate(epoch);
    System.out.println(date);

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

如果我没有弄错,那么您真正需要的是一种将从历元开始的毫秒值转换为日期的方法,在这种方法中,天不会更改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 =  1525033875230L; // Obtained from some dataset
LocalDate localDate = LocalDateTime
  .ofInstant(Instant.ofEpochMilli(epoch), 
             ZoneId.of("Europe/Amsterdam"))
  .toLocalDate();
    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
通过打印
即时
可以看到时间在午夜之后(实际上是阿姆斯特丹时区的03:14:35.230)。该方法正确地认为这一时间属于4月29日,而不是4月30日


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

如果我没有弄错的话,你真正需要的是一种将从历元开始的毫秒值转换为日期的方法,在这种方法中,天不会改变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 =  1525033875230L; // Obtained from some dataset
LocalDate localDate = LocalDateTime
  .ofInstant(Instant.ofEpochMilli(epoch), 
             ZoneId.of("Europe/Amsterdam"))
  .toLocalDate();
    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
通过打印
即时
可以看到时间在午夜之后(实际上是阿姆斯特丹时区的03:14:35.230)。该方法正确地认为这一时间属于4月29日,而不是4月30日


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

在夏时制期间,你仍然希望工作日在当地时间4:00结束,对吗?还是希望在夏令时5点结束?如果是前一种情况,请使用
LocalTime
。我们总是需要LocalTime,因此在我们的代码中,我们必须将其用于我正在寻找的自定义时区。我的意思是,您可能不需要
TimeZoneInfo
。无论一年中的什么时候,工作日都会在时钟显示4:00时结束,对吗?这是
java.time.LocalTime
的一个用例。做不正确的事情的正确方法是什么?很难说。:-)您是否考虑过在整个过程中使用
LocalDateTime
是否适合您?它没有时区。当然,它也不能给你一个时区能给你的东西。在夏时制期间,你仍然希望工作日在当地时间4:00结束,对吗?还是希望在夏令时5点结束?如果是前一种情况,请使用
LocalTime
。我们总是需要LocalTime,因此在我们的代码中,我们必须将其用于我正在寻找的自定义时区。我的意思是,您可能不需要
TimeZoneInfo
。无论一年中的什么时候,工作日都会在时钟显示4:00时结束,对吗?这是
java.time.LocalTime
的一个用例。做不正确的事情的正确方法是什么?很难说。:-)您是否考虑过在整个过程中使用
LocalDateTime
是否适合您?它没有时区。当然,它也不能给你时区给你的东西。。