【问题标题】:Convert OffsetDateTime to LocalDateTime with correct offset in java 8在 java 8 中使用正确的偏移量将 OffsetDateTime 转换为 LocalDateTime
【发布时间】:2021-08-27 07:19:33
【问题描述】:

当我尝试从 java.time 将 OffsetDateTime 转换为 LocalDateTime 时,我希望生成的 LocalDateTime 将使用本地时区进行更新。所以,如果我有 2011-12-03T10:00:00ZOffsetDateTime,并且我的本地时区是 UTC+2,我希望 LocalDateTime 是 2011-12-03T12:00:00,但我得到的是 2011-12-03T10:00:00。我正在使用OffsetDateTime 拥有的方法toLocalDateTime() 对其进行转换。好像只是截断了日期,去掉了偏移部分,没有调整时间。

所以我试图找出一种方法来获得一个LocalDateTime,它代表本地日期时间,同时考虑到区域偏移量。按照例子,我想得到2011-12-03T12:00:00

【问题讨论】:

  • “本地时区”是什么意思有点不清楚。请记住,您使用的是 offset 日期时间,而不是 zoned 日期时间,所以我假设您的意思是“本地偏移量”。然而,这是模棱两可的。您是指瞬间2011-12-03T10:00:00Z 的本地偏移量,还是指现在 的本地偏移量?请注意,本地偏移量可能会发生变化。
  • “好像只是截断了日期,去掉了偏移部分,没有调整时间” ..没错,方法描述就是这么说的(docs.oracle.com/javase/8/docs/api/java/time/… )。此外,LocalDateTime 中的“本地”部分并不意味着它会影响您的实际本地时区,它只是意味着它代表一个对任何当前本地时区/偏移有效的时间,无论它可能是什么。

标签: java time timezone


【解决方案1】:

LocalDateTime 将为您提供 OffsetDateTime 的挂钟时间。现在是 10:00

您需要先转换为您所在时区的 ZonedDatedTime

这样

OffsetDateTime off = OffsetDateTime.of(2011,12,3,10,00,0,0, ZoneOffset.UTC);
ZonedDateTime zoned = off.atZoneSameInstant(ZoneId.of("Europe/Athens"));
LocalDateTime athensWallTime = zoned.toLocalDateTime();
System.out.println(athensWallTime);

【讨论】:

    【解决方案2】:

    我想你要找的是OffsetDateTime.atZoneSameInstant:

    OffsetDateTime.parse("2011-12-03T10:00:00Z")
        .atZoneSameInstant(ZoneId.systemDefault())
        .toLocalDateTime()
    

    【讨论】:

      【解决方案3】:

      OffsetDateTime#withOffsetSameInstant

      如果您需要将OffsetDateTime 的对象转换为具有不同ZoneOffsetOffsetDateTime 对象,您可以使用OffsetDateTime#withOffsetSameInstant 来实现。

      演示:

      import java.time.LocalDateTime;
      import java.time.OffsetDateTime;
      import java.time.ZoneOffset;
      
      public class Main {
          public static void main(String[] args) {
              OffsetDateTime odt = OffsetDateTime.parse("2011-12-03T10:00:00Z");
      
              OffsetDateTime odtWithOffsetTwoHours = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
              System.out.println(odtWithOffsetTwoHours);
      
              LocalDateTime ldt = odtWithOffsetTwoHours.toLocalDateTime();
              System.out.println(ldt);
          }
      }
      

      输出:

      2011-12-03T12:00+02:00
      2011-12-03T12:00
      

      ONLINE DEMO

      我建议你继续使用OffsetDateTime,因为LocalDateTime,顾名思义,会丢弃有用的时区信息。不过,LocalDateTimethis page 中提到的某些场景中很有用。

      如果您正在处理 JDBC,请检查 this answerthis answer

      Trail: Date Time 了解有关现代日期时间 API 的更多信息。

      【讨论】:

        【解决方案4】:

        这里有一些你可以试试的代码:

        public static void main(String[] args) {
                OffsetDateTime offsetDT1 = OffsetDateTime.now();
                System.out.println("OffsetDateTime1: " + offsetDT1);
         
                OffsetDateTime offsetDT2 = OffsetDateTime.now(Clock.systemUTC());
                System.out.println("OffsetDateTime2: " + offsetDT2);
                
                OffsetDateTime offsetDT3 = OffsetDateTime.now(ZoneId.of("Asia/Jakarta"));
                System.out.println("OffsetDateTime3: " + offsetDT3);
                
                OffsetDateTime offsetDT4 = OffsetDateTime.of(1980, 4, 9, 20, 15, 45, 345875000, ZoneOffset.of("+07:00"));
                System.out.println("OffsetDateTime4: " + offsetDT4);
                
                OffsetDateTime offsetDT5 = OffsetDateTime.of(LocalDate.now(), LocalTime.of(15, 50, 25), ZoneOffset.of("+07:00"));
                System.out.println("OffsetDateTime5: " + offsetDT5);
                
                OffsetDateTime offsetDT6 = OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.of("+07:00"));
                System.out.println("OffsetDateTime6: " + offsetDT6);
                
                OffsetDateTime offsetDT7 = OffsetDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
                System.out.println("OffsetDateTime7: " + offsetDT7);
                
                OffsetDateTime offsetDT8 = OffsetDateTime.parse("2019-08-31T15:20:30+08:00");
                System.out.println("OffsetDateTime8: " + offsetDT8);
                
                OffsetDateTime offsetDT9 = OffsetDateTime.parse("1980-04-09T08:20:45+07:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
                System.out.println("OffsetDateTime9: " + offsetDT9);
        

        输出

        OffsetDateTime1: 2019-08-31T23:49:05.629+08:00
        OffsetDateTime2: 2019-08-31T15:49:05.630Z
        OffsetDateTime3: 2019-08-31T22:49:05.630+07:00
        OffsetDateTime4: 1980-04-09T20:15:45.345875+07:00
        OffsetDateTime5: 2019-08-31T15:50:25+07:00   
        OffsetDateTime6: 2019-08-31T23:49:05.631+07:00
        OffsetDateTime7: 2019-08-31T23:49:05.631+08:00
        OffsetDateTime8: 2019-08-31T15:20:30+08:00
        OffsetDateTime9: 1980-04-09T08:20:45+07:00
        

        您可以查看此website 以获得更多解释或浏览javadoc wbsite

        【讨论】:

        • 所有代码的哪一部分应该是问题的答案?
        • 根据我给出的输出,你可以选择一个你想要使用的函数。
        • 那些更改 2011-12-03T10:00:00Z(输入OffsetDateTime)到2011-12-03T12:00:00(输入LocalDateTime)?这个答案中没有LocalDateTime,也没有OffsetDateTime 的转换来将时间从10 更改为12,所以这将是:没有一个。
        • 对于#7,OffsetDateTime.ofInstant(Instant.now(), ZoneId.systemDefault())OffsetDateTime.now() 的长篇大论。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        • 1970-01-01
        相关资源
        最近更新 更多