2

我正在尝试从具有以下条件的对象( ) 生成Date对象 ( ):java.util.DateLocalDatejava.time.LocalDate

  • Date允许一个可以从对象中减去一定天数的参数
  • 将日期和时间设为当前 UTC 中的日期和时间
  • 在一天的开始有时间,即00:00:00
  • 时区戳(即 CDT 或 UTC)是无关紧要的,因为我从String

为了满足这个标准,我创建了一个测试程序,但是当我修改LocalDate. 请参见下面的代码:

  public static void main (String args[]) {
    Long processingDaysInPast = 0L;
    LocalDate createdDate1 = LocalDate.now(Clock.systemUTC()).minusDays(processingDaysInPast);
    LocalDate createdDate2 = LocalDate.now(Clock.systemUTC()).minusDays(processingDaysInPast);
    System.out.println(createdDate1);
    System.out.println(createdDate1.atStartOfDay().toInstant(ZoneOffset.UTC));
    System.out.println(Date.from(createdDate1.atStartOfDay().toInstant(ZoneOffset.UTC)));
    System.out.println((createdDate2.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
    System.out.println(Date.from(createdDate2.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
}

输出:

 2017-08-14
 2017-08-14T00:00:00Z
 Sun Aug 13 19:00:00 CDT 2017
 2017-08-14
 2017-08-14T05:00:00Z
 Mon Aug 14 00:00:00 CDT 2017

当我添加值时,Date.from(createdDate1.atStartOfDay().toInstant(ZoneOffset.UTC))我得到了日期的预期输出,带有00:00:00时间字段。但是,如果我不添加这个参数,例如:Date.from(createdDate2.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())我得到了前一天的结果,19:00:00为什么会这样?

我的主要目标是能够Date使用当前的 UTC 日期和时间归零 ( StartOfDay) 来捕获对象。

4

1 回答 1

2

当你这样做时:

createdDate2.atStartOfDay().atZone(ZoneId.systemDefault())

首先,createdDate2.atStartOfDay()返回 a LocalDateTime,相当于2017-08-14午夜。ALocalDateTime不是时区感知的。

当您调用 时,它会在系统的默认时区( ) 中atZone(ZoneId.systemDefault())创建ZonedDateTime具有相应日期 (2017-08-14) 和时间(午夜)的a 。在您的情况下,默认时区不是 UTC(它是“CDT”,因此 CDT 已经到了午夜 - 只需检查您的默认时区是什么)。ZoneId.systemDefault()System.out.println(ZoneId.systemDefault())

要获取UTC午夜的日期,您可以将默认时区 ( ZoneId.systemDefault()) 替换为 UTC ( ZoneOffset.UTC):

Date.from(createdDate2.atStartOfDay().atZone(ZoneOffset.UTC).toInstant())

或者(更短的版本):

Date.from(createdDate2.atStartOfDay(ZoneOffset.UTC).toInstant())

当然,您也可以使用与以下相同的方式进行操作createdDate1

Date.from(createdDate2.atStartOfDay().toInstant(ZoneOffset.UTC))

它们都是等效的,将导致UTC的午夜。


只是一个简短的说明:短时区名称类似于CDTPST不是真正的时区。
API 使用IANA 时区名称(始终采用格式Region/City,例如America/ChicagoEurope/Berlin)。避免使用 3 个字母的缩写(如CDTor PST),因为它们模棱两可且不标准

许多不同的时区可以CDT用作缩写。发生这种情况是因为时区是一个区域在历史上拥有、拥有和将拥有的所有不同偏移量的集合。今天很多地方都在用CDT,不代表过去都在同一时期用,也不代表以后都用。由于历史不同,会为每个地区创建一个时区。

于 2017-08-14T18:19:36.173 回答