【问题标题】:How to obtain the end of the day when given a LocalDate?给定LocalDate时如何获得一天的结束?
【发布时间】:2016-07-24 08:13:23
【问题描述】:

当给定一个 LocalDate 时如何获得一天的结束时间?

我可以通过做得到它

LocalDateTime.of(LocalDate.now(), LocalTime.of(23, 59, 59));

但是有一个等效的“atStartOfDay”方法来结束一天的工作吗?

LocalDate.now().atStartOfDay();
LocalDate.now().atEndOfDay(); //doesn't work

【问题讨论】:

  • “一天结束”是什么意思?第二天的开始时间减去 1 秒? 1毫秒? 1纳秒?为什么不只使用第二天的开始,并使用[day, day + 1[ 间隔?当商店从早上 8 点营业到下午 6 点时,显示的结束时间是下午 6 点,而不是下午 5:59:59。
  • 此答案还包含 ZonedDateTime stackoverflow.com/a/50400321/1658268 的解决方案

标签: java java-time


【解决方案1】:

这些是LocalTime 中可用的变体,注意MIDNIGHTMIN 是相等的。

LocalDate.now().atTime(LocalTime.MIDNIGHT); //00:00:00.000000000
LocalDate.now().atTime(LocalTime.MIN);      //00:00:00.000000000
LocalDate.now().atTime(LocalTime.NOON);     //12:00:00.000000000
LocalDate.now().atTime(LocalTime.MAX);      //23:59:59.999999999

供参考,这是java.time.LocalTime中的实现

/**
 * Constants for the local time of each hour.
 */
private static final LocalTime[] HOURS = new LocalTime[24];
static {
    for (int i = 0; i < HOURS.length; i++) {
        HOURS[i] = new LocalTime(i, 0, 0, 0);
    }
    MIDNIGHT = HOURS[0];
    NOON = HOURS[12];
    MIN = HOURS[0];
    MAX = new LocalTime(23, 59, 59, 999_999_999);
}

如果分配给LocalTime(代表nanoOfSecond)的第四个构造函数参数(999_999_999)的值看起来不熟悉,那是因为它使用了Java 7 特性Underscores in Numeric Literals

在 Java SE 7 及更高版本中,任意数量的下划线字符 (_) 可以出现在数字文字中数字之间的任何位置。例如,此功能使您能够分隔数字文字中的数字组,从而提高代码的可读性。

【讨论】:

    【解决方案2】:
    public static long getStartOfDay(String country) {
        return LocalDate.now().atStartOfDay(ZoneId.of("Europe/Berlin")).toInstant().toEpochMilli();
    }
    
    public static long getEndOfDay(long startOfDay) {
        return startOfDay + 86399000L;  // adding 24h = 1day seconds - 1
    }
    
    public static long getStartOfDay(LocalDate localDate, String country) {
        return localDate.atStartOfDay(ZoneId.of("Europe/Berlin")).toInstant().toEpochMilli();
    }
    
    public static long getEndOfDay(LocalDate localDate, String country) {
        localDate = localDate.plusDays(1L);
        return localDate.atStartOfDay(ZoneId.of("Europe/Berlin")).toInstant().toEpochMilli() - 1000L; //substract mili
    }
    

    【讨论】:

      【解决方案3】:

      这里有一些替代方案,具体取决于您的需要:

      LocalDate.now().atTime(23, 59, 59);     //23:59:59
      LocalDate.now().atTime(LocalTime.MAX);  //23:59:59.999999999
      

      但是没有内置方法。

      正如@JBNizet 所评论的,如果你想创建一个间隔,你也可以使用一个直到午夜的间隔,独占。

      【讨论】:

      • 夏令时怎么样?
      • @MateusViccari LocalDate / LocalDateTime 没有时区,因此没有 DST 规则。不知道你在问什么。
      【解决方案4】:

      获取第二天的开始并从中减去 1 秒。这应该适合你。 :

      public static void main(String[] args) {
      
          LocalDate date = LocalDate.now();
          LocalDateTime dt = date.atStartOfDay().plusDays(1).minusSeconds(1);
          System.out.println(dt);
      }
      

      O/P:

      2016-04-04T23:59:59
      

      【讨论】:

      • 请注意,这是 1 秒,而不是 1 毫秒,我建议不要使用这种 hack
      • 这太棒了!!
      • 这只会为您提供 23:59:59.000000000 的时间。因此,如果您使用此解决方案,您应该意识到这一点。使用公认的答案更安全:stackoverflow.com/a/36408726/2294031
      猜你喜欢
      • 2012-04-29
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      • 2014-08-09
      相关资源
      最近更新 更多