【问题标题】:How to get zone name that respects daylight saving (e.g. EDT)如何获取尊重夏令时的区域名称(例如 EDT)
【发布时间】:2019-11-27 10:58:09
【问题描述】:

我有 ZonedDateTime 实例,试图将区域作为字符串(例如 EST/EDT)获取,如下所示:

merchantLocalReceiptDateTime.getZone().getDisplayName(TextStyle.SHORT, Locale.getDefault())

对于我的设置,它返回给我 EST,而实际上我期待的是 EDT。请告知如何获取正确反映夏令时的区域字符串。

【问题讨论】:

    标签: java-time threetenbp


    【解决方案1】:
    //SHORT: CEST
    DateTimeFormatter.ofPattern("zzz").format(zonedDateTime)
    
    //SHORT: CET 
    ZoneId.getDisplayName(TextStyle.SHORT,Locale.ENGLISH)    
    
    //LONG: Central European Summer Time
    DateTimeFormatter.ofPattern("zzzz").format(zonedDateTime)
    
    //LONG: Central European Time
    ZoneId.getDisplayName(TextStyle.LONG,Locale.ENGLISH)
    
    //Use this for converting CET to CEST and vice versa
    TimeZone tz = TimeZone.getTimeZone(timeZone.getZone());
    tz.getDisplayName(true, TimeZone.SHORT, Locale.ENGLISH));
    

    【讨论】:

      【解决方案2】:

      好的,我不喜欢这个解决方案,但它是迄今为止我想出的唯一一个,唯一一个有效的:

      所以我们已经预初始化了ZonedDateTime merchantLocalReceiptDateTime(记住,这是threetenbp)。我们可以这样做(在给定时间是夏令时吗?):

      boolean isDaylightSaving = merchantLocalReceiptDateTime.getZone()
                      .getRules().isDaylightSavings(merchantLocalReceiptDateTime.toInstant());
      

      然后,为了获得尊重夏令时的时区的简短表示,我们可以这样做(TimeZone 不是 threeten 的一部分,它是 java.util):

      TimeZone.getTimeZone(merchantLocalReceiptDateTime.getZone().getId())
                      .getDisplayName(isDaylightSaving, TimeZone.SHORT)
      

      对于纽约(假设设备语言为英语/美国),以上代码在冬季产生 EST,现在产生 EDT。对于没有特定夏令时名称的时区,它可以给出例如“GMT+2”、“GMT+3”等。如果语言不同,您可能会得到那些“GMT+-”。

      【讨论】:

        【解决方案3】:
             static DateTimeFormatter etFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mma 'ET'");
        
              static ZoneId istZoneId = ZoneId.of("Asia/Kolkata");
              static ZoneId etZoneId = ZoneId.of("America/New_York");
        
         LocalDateTime currentDateTime = LocalDateTime.now();
        
            ZonedDateTime currentISTime = currentDateTime.atZone(istZoneId);                
            ZonedDateTime currentETime = currentISTime.withZoneSameInstant(etZoneId);       //ET Time
        
            System.out.println(etFormat.format(currentETime));
        

        【讨论】:

        • 谢谢,我使用的是threetenbp,所以不能使用以上作为答案,但即使我愿意,我猜以上会给我更多的打击?
        • 也许你得到了帮助:github.com/JakeWharton/ThreeTenABP
        • 是的,我已经拥有基于即时和 ZoneId 信息创建的 ZoneDateTime 实例。问题不在于创建 ZoneDateTime,而在于读取其区域信息 - 以用户友好的方式,如果适用,尊重日光。
        • @ror 现在检查更新的答案......我希望它现在对你有用!
        • 感谢您的努力!刚才跑了,它给了我:美国东部时间 2019 年 7 月 24 日上午 04:59,但是我想要完成的是获取时区。对于纽约的“现在”,它应该是 EDT,但是即使使用你的方法我得到 EST - 这就是问题所在。我很困惑为什么在 android 中处理日期如此困难。
        猜你喜欢
        • 2020-08-02
        • 2019-06-17
        • 2011-08-22
        • 1970-01-01
        • 2021-12-24
        • 2016-08-07
        • 1970-01-01
        • 2021-11-27
        相关资源
        最近更新 更多