java 中的几个时区未设置偏移量

Offset is not set for few time zone in java

我想从用户那里获取时间和时区并创建一个条目。在日历下方使用 API 来执行此操作,它适用于少数时区而不适用于少数时区

calendar.setTime(eventFormEntryBean.getStartDate());
TimeZone timeZone = TimeZone.getTimeZone("Europe/Amsterdam");
calendar.setTimeZone(timeZone);

工作时区(最后+xx:xx)

不工作时区:-

以上伦敦和Africa/Dakar时区没有任何区分时区的标志,只是在末尾注明“.000Z”。是否需要设置任何属性才能获得完整时区? .000z 是什么意思?

如果您希望能够编写反映偏移量和时区之间差异的代码,请保留 java.util 并切换到 java.time(对于 Java 8+ 和support library for Java 6 and 7).

然后你可以这样做:

public static void main(String[] args) {
    /*
     * the base of this example is a date time with an offset of +01:00
     * (which is present in several zones, not just in Europe/Amsterdam!)
     */
    String datetime = "2019-11-28T12:49:24.000+01:00";
    // parse it to an offset-aware object
    OffsetDateTime plusOneHourOffsetDateTime = OffsetDateTime.parse(datetime);
    // print it to be sure ;-)
    System.out.println(plusOneHourOffsetDateTime
            .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
    // convert it to a zone-aware date time object by providing the zone
    ZonedDateTime europeAmsterdamZonedDateTime = plusOneHourOffsetDateTime
            .atZoneSameInstant(ZoneId.of("Europe/Amsterdam"));
    // print it
    System.out.println(europeAmsterdamZonedDateTime
            .format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // then take the same instant but use a different time zone
    ZonedDateTime utcZonedDateTime = plusOneHourOffsetDateTime
            .atZoneSameInstant(ZoneId.of("UTC"));
    // print that, it adds a Z (indicating an offset of 00:00) and the time zone
    // that was specified
    System.out.println(utcZonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // take a totally different time zone and do it again
    ZonedDateTime pacificPalauZonedDateTime = plusOneHourOffsetDateTime
            .atZoneSameInstant(ZoneId.of("Pacific/Palau"));
    // print that one, too
    System.out.println(pacificPalauZonedDateTime
            .format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

输出这个

2019-11-28T12:49:24+01:00
2019-11-28T12:49:24+01:00[Europe/Amsterdam]
2019-11-28T11:49:24Z[UTC]
2019-11-28T20:49:24+09:00[Pacific/Palau]

编辑

The reason for the DateTimeParseException mentioned in your comment is the date-time String, because it doesn't have a zone or an offset, which makes it unparseable by the default DateTimeFormatter used in OffsetDateTime.parse(String datetime).

如果 String 包含日期和时间信息但没有区域或偏移量,您可以先将其解析为 LocalDateTime 并从中创建 ZonedDateTime

public static void main(String[] args) {
    // date time String without zone or offset information
    String dateTimeString = "2019-11-30T19:35:06";
    // create a LocalDateTime from the String
    LocalDateTime ldt = LocalDateTime.parse(dateTimeString);
    // then create a ZonedDateTime from the LocalDateTime adding a zone
    ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault()); // system default here
    // and print it
    System.out.println(zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

你误会了。 Z 的含义与 +00:00 完全相同,并且是以您正在生成的 ISO 8601 格式编写它的常规推荐方式。因此,对于您所有的时区,您都会获得正确的 UTC 偏移量(IST 可能除外;这可能代表爱尔兰夏令时或以色列标准时间,在这种情况下,+05:30 的偏移量是错误的;不要依赖模棱两可的三个字母的大部头区域缩写)。

CalendarTimeZone 类 的设计都很糟糕,而且早就过时了。我建议不要使用 java.time,而是现代的 Java 日期和时间 API。您需要 ZoneIdZonedDateTime。查看 deHaar 的回答。