【问题标题】:Convert Date and Time with different timezones to timestamp将具有不同时区的日期和时间转换为时间戳
【发布时间】:2020-03-17 04:50:13
【问题描述】:

在 Java 中遇到了一个小问题:我有两个字符串,分别代表一个日期(例如“2019-11-10”)和一个时间(例如“01:23:45.123”)。将它们转换为 UTC 时间戳很容易,但有一个问题:

日期以当地时区给出,例如“America/New_York”,而时间以 UTC 给出,因此以下信息...

date = "2019-11-10"time="01:23:45.123"(假设日期部分的本地时区为"America/New_York"

...实际上是 UTC 时间 "2019-11-11 01:23:45.123"(因为只有纽约日期为“2019-11-10”)。

Java Time API 或 joda time 是否提供任何方便的方法来进行此转换,同时牢记 DST 等细节?有没有(相对)简单的方法可以做到这一点?

编辑:

也许这有点不清楚。让我试着从另一面解释一下:

假设我的 DateTime x(UTC 时间)为"2019-11-11 01:23:45.123"

然后我可以通过简单地将 x 转换为适当的时区并相应地格式化来获取日期部分 y(如“America/New_York”中所示) -> "2019-11-10"

我还可以通过简单地相应地格式化来获取时间部分 z(如 UTC 所示) - "01:23:45.123"

现在,假设我有 y 和 z - 我如何获得 x?

编辑 2:

我刚刚意识到,这将永远不会完美地工作。原因:

UTC“2019-11-04 04:01:00.000”-> 美国/纽约:“2019-11-03 23:01”

UTC“2019-11-03 04:01:00.000”-> 美国/纽约:“2019-11-03 00:01”

所以,如果我只得到信息“美国/纽约的日期”是“2019-11-03”加上“UTC 时间”是“04:01:00.000”,那么实际上有两种可能的解决方案,而不仅仅是一个.

【问题讨论】:

  • 你检查了吗ZonedDateTime
  • 在时区中给出日期是什么意思?
  • 我试图澄清一下...

标签: java time jodatime java-time


【解决方案1】:

您必须将日期调整为纽约时区,这可以通过选择任意时间来完成。然后通过选择任意日期将时间转换为纽约。然后可以将两者合并,因为它们具有相同的区域。并转换回 UTC

    LocalDate date = LocalDate.parse("2019-11-10");
    LocalTime time = LocalTime.parse("01:23:45.123");
    ZoneId zone = ZoneId.of("America/New_York");

    ZonedDateTime dateInZone = date.atStartOfDay(zone);
    ZonedDateTime timeInZone = time.atOffset(ZoneOffset.UTC).atDate(date).atZoneSameInstant(zone);
    ZonedDateTime resultNY = dateInZone.with(timeInZone.toLocalTime());
    ZonedDateTime resultUTC = resultNY.withZoneSameInstant(ZoneOffset.UTC)
    System.out.println(resultUTC);
    // 2019-11-11T01:23:45.123Z

【讨论】:

  • 虽然大体如此,但我的主要问题是夏令时。在那些特定的日子里,随机时间不起作用,因为它实际上很重要...... 99% 的解决方案实际上非常简单,真的。但不幸的是,剩下的 1% 更难。
【解决方案2】:

日期不能有时区。 (想一想。)

也许您的意思是 UTC 中该日期的第一刻。

LocalDate ld = LocalDate.parse( "2019-11-10" ) ;
ZonedDateTime zdt = ld.atStartOfDay( ZoneOffset.UTC ) ; 

调整那个时刻以在时区看到。

ZoneId z = ZoneId.of( "America/New_York" ) ;
LocalTime lt = LocalTime.parse( "01:23:45.123" ) ;
ZonedDateTime zdt2 = zdt.with( lt ) ;

【讨论】:

  • 是的,通常时间不能有时区。在这种情况下,它确实:让我们暂时调用最后的 dateTime x:在这种情况下,我可以通过简单地将 x 转换为所需的时区并适当地格式化它来获取日期部分 String y。我通过在 UTC 中转换(或保留)x 然后适当地格式化它来获得时间部分 String z。问题是:给定 y 和 z,我怎样才能得到 x?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多