【问题标题】:How to know current timezone of Ireland in a given time in java如何在java中的给定时间内知道爱尔兰的当前时区
【发布时间】:2021-11-27 17:13:31
【问题描述】:

在夏天,爱尔兰在冬天使用IST, UTC+01:00Greenwich Mean Time。我从来源获得的日期时间没有任何 GMT 信息,它来自爱尔兰。我需要将其转换为 GMT+0。但挑战在于不同季节的爱尔兰时区不同。

【问题讨论】:

  • 那是不可能的。一些时间戳对应于两个不同的时刻。

标签: java time


【解决方案1】:

我建议您使用ZonedDateTime (reference documentation) 和ZoneId,您应该使用Europe/Dublin。它应该根据季节观察时区的变化。

【讨论】:

    【解决方案2】:

    如果您确定时间来自爱尔兰,您可以硬编码 ZoneId,例如:ZoneId.of("Europe/Dublin")

    然后像这样解析爱尔兰的时间:

    LocalDateTime ldt = LocalDateTime.parse("2018-07-01T08:00");
    ZoneId zoneId = ZoneId.of("Europe/Dublin");
    ZonedDateTime zdt = ZonedDateTime.of(ldt, zoneId); 
    

    更多关于 ZonedDateTime 的信息在这里: https://www.codebyamir.com/blog/add-a-timezone-to-localdatetime-with-zoneddatetime-in-java-8

    【讨论】:

      【解决方案3】:

      tl;博士

      ZonedDateTime
      .of( 
          LocalDate.parse( "2022-06-23" ) , 
          LocalTime.parse( "15:30" ) , 
          ZoneId.of( "Europe/Dublin" )  
      )
      .toInstant()
      .atOffset(
          ZoneOffset.UTC
      )
      

      看到这个code run live at IdeOne.com。我们看到明年夏天,爱尔兰人民的时钟将比 UTC 时间提前一小时:都柏林时间的 15:30 将是 UTC 时间的 14:30。

      2022-06-23T14:30Z

      详情

      你的标题要求:

      如何在java中知道给定时间内爱尔兰的当前时区

      爱尔兰??只有一个时区,根据我对this Wikipedia article的阅读:Europe/Dublin

      您将偏移量与区域混淆了。

      与 UTC 的偏移只是比现代时间子午线提前或落后几个小时-分钟-秒。

      时区要多得多。时区是一个命名的过去、现在和未来对偏移量变化的历史,该偏移量由特定地区的人们使用,由他们的政治家决定。

      实时时区以Continent/Region 格式命名。 IST 等 2-4 个字符的伪区域不是时区,应该避免,因为它们不标准化,甚至不是唯一的!对某些人来说,IST爱尔兰标准时间,而对另一些人来说IST印度标准时间

      你说:

      我从某个来源获得的日期时间没有任何 GMT 信息,而且它来自爱尔兰。

      因此,请获取您的日期和时间,并添加您认为预期的时区。你会得到一个ZonedDateTime 来代表一个时刻,即时间线上的一个特定点。

      LocalDate ld = … ;
      LocalTime lt = … ;
      ZoneId z = ZoneId.of( "Europe/Dublin" ) ;
      ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
      

      通过提取 Instant 来调整到 UTC(零时分秒的偏移量)。

      Instant instant = zdt.toInstant() ;
      

      要获得更大的灵活性,例如生成各种格式的文本,请转换为OffsetDateTime

      OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
      

      【讨论】:

        【解决方案4】:

        你不能(总是)

        只是为了说明我认为 talex 在评论中的含义。在 10 月的最后一个星期日,爱尔兰从夏令时转换为标准时间。爱尔兰的时钟从凌晨 2 点调回凌晨 1 点。因此,在凌晨 1 点之后的一个小时,又是凌晨 1 点。时代在重复。这称为重叠。 (相反,当时钟向前转动时,称为间隙。)这意味着什么?例如,如果你得到的时间是那天晚上 1:30,你不知道它是从第一次是 1:30 — 1:30 IST — 还是第二次是 1:30 — 1 :30 格林威治标准时间。或者在代码中:

            String dateTimeStr = "2021-10-31T01:30:00";
            LocalDateTime ldt = LocalDateTime.parse(dateTimeStr);
            
            System.out.println(ldt.atZone(IRELAND).withEarlierOffsetAtOverlap());
            System.out.println(ldt.atZone(IRELAND).withLaterOffsetAtOverlap());
        

        我使用了这个常量:

        private static final ZoneId IRELAND = ZoneId.of("Europe/Dublin");
        

        输出是:

        2021-10-31T01:30+01:00[Europe/Dublin]
        2021-10-31T01:30Z[Europe/Dublin]
        

        对于不是源自当晚那两个小时的时间戳,您不会有任何问题。

        要检查您是否有不明确的时间戳,请比较我在上述代码中打印的两个 ZonedDateTime 对象。对于绝大多数情况,它们将是平等的。举个例子:

            String dateTimeStr = "2021-10-07T18:48:00";
        
        2021-10-07T18:48+01:00[Europe/Dublin]
        2021-10-07T18:48+01:00[Europe/Dublin]
        

        【讨论】:

        • 哇!多么巧合!另一个有用的答案,几乎在我发布答案的同时发布!
        【解决方案5】:

        现有的答案很好。但是,他们错过了 OP 需要的重要信息,该信息是:

        ZonedDateTime 旨在自动调整时区偏移量。

        这意味着根据 Date-Time 是否为夏季/冬季时间,您会发现它反映了不同的时区偏移量(当然,如果DST 适用)。

        演示:

        import java.time.LocalDate;
        import java.time.ZoneId;
        import java.time.ZonedDateTime;
        
        public class Main {
            public static void main(String[] args) {
                ZoneId zoneId = ZoneId.of("Europe/Dublin");
                ZonedDateTime zdtSummerIST = LocalDate.of(2021, 6, 15).atStartOfDay(zoneId);
                ZonedDateTime zdtWinterIST = LocalDate.of(2021, 11, 15).atStartOfDay(zoneId);
                System.out.println(zdtSummerIST);
                System.out.println(zdtWinterIST);
            }
        }
        

        输出:

        2021-06-15T00:00+01:00[Europe/Dublin]
        2021-11-15T00:00Z[Europe/Dublin]
        

        ONLINE DEMO

        输出中的Z 是零时区偏移的timezone designator。它代表 Zulu 并指定 Etc/UTC 时区(时区偏移量为 +00:00 小时)。

        如何将没有时区的日期时间字符串转换为ZonedDateTime

        将不带时区的日期时间字符串解析为LocalDateTime,可以使用LocalDateTime#atZone 将其转换为ZonedDateTime

        演示:

        import java.time.LocalDateTime;
        import java.time.ZoneId;
        import java.time.ZonedDateTime;
        import java.time.format.DateTimeFormatter;
        import java.util.Locale;
        
        public class Main {
            public static void main(String[] args) {
                ZoneId zoneId = ZoneId.of("Europe/Dublin");
                String input = "07/10/2021 18:50:15";
                DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss", Locale.ENGLISH);
                LocalDateTime ldt = LocalDateTime.parse(input, dtf);
                ZonedDateTime zdt = ldt.atZone(zoneId);
                System.out.println(zdt);
            }
        }
        

        输出:

        2021-10-07T18:50:15+01:00[Europe/Dublin]
        

        ONLINE DEMO

        通过 Trail: Date Time 了解有关 modern Date-Time API* 的更多信息。


        * 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring。请注意,Android 8.0 Oreo 已经提供了support for java.time

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多