Библиотека времени Java8 неправильно интерпретирует часовой пояс BST - PullRequest
1 голос
/ 14 июня 2019

Это не дублирование другого вопроса о часовом поясе, потому что у меня нет роскоши выбирать формат часового пояса. Я нахожусь в процессе миграции моего кода Java для использования новой библиотеки времени java8, но я обнаружил, что DateTimeFormatter неправильно интерпретирует часовой пояс "BST" (British Summer Time). Вместо того, чтобы сделать его UTC + 0100, он преобразовал его в часовой пояс Pacific / Bougainville. Кто-нибудь знает, как я могу это исправить, не возвращаясь к старому SimpleDateFormat, или использовать явно установленный часовой пояс, потому что мой код должен работать в нескольких регионах мира? Этот формат отметки времени получается путем запроса другой системы, поэтому я не смогу ее изменить. Кажется, SimpleDateFormat может правильно распознать часовой пояс. Мой тестовый код ниже:

public static void main(String[] args) throws ParseException {
    String sTime = "Fri Jun 07 14:07:07 BST 2019";
    DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE MMM dd kk:mm:ss z yyyy");
    ZonedDateTime zd = ZonedDateTime.parse(sTime, FORMATTER);
    System.out.println("The time zone: " + zd.getZone());
    FileTime ftReturn = FileTime.from(zd.toEpochSecond(), TimeUnit.SECONDS);
    System.out.println("File time is: " + ftReturn);

    DateFormat df = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy", Locale.ENGLISH);
    Date dtDD = df.parse(sTime);
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dtDD);
    FileTime ftReturn1 = FileTime.fromMillis(calendar.getTimeInMillis());
    System.out.println("File time1 is:  " + ftReturn1);
}

Результат теста:
Часовой пояс: Тихий океан / Бугенвиль
Время файла: 2019-06-07T03: 07: 07Z
Время файла1: 2019-06-07T13: 07: 07Z

Ответы [ 2 ]

3 голосов
/ 14 июня 2019

Согласно https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html#SHORT_IDS:

BST - Азия / Дакка

Так что, думаю, вам не следует использовать это сокращение.

РЕДАКТИРОВАТЬ: Только что нашел этот вопрос , который отвечает на него.

Так что не используйте Бангладешское стандартное время;) Вместо этого используйте ZoneId.of("Europe/London")

1 голос
/ 16 июня 2019

Во-первых, вы пытаетесь решить задачу, которая не может быть решена. Трехбуквенные сокращения часовых поясов неоднозначны, я думаю, чаще всего нет. Поэтому, если вы решите проблему для Европы / Лондона, у вас будет это снова, когда вы встретитесь с EST, IST, CST, CDT, PST, WST и так далее, и так далее. Или когда вы встречаете строку, где BST должен был означать летнее время Бразилии, стандартное время Бангладеш или стандартное время Бугенвиля. Еще больше интерпретаций существует. Вместо этого получите однозначную строку, такую ​​как строка со смещением UTC, а не сокращение часового пояса, лучше всего строку в формате ISO 8601, например 2019-06-07T14:07:07+01:00.

Но если вы уверены, что BST всегда будет означать британское летнее время в вашем мире, близорукое решение может заключаться в том, чтобы сообщить DateTimeFormatter, какой часовой пояс вы предпочитаете:

    String sTime = "Fri Jun 07 14:07:07 BST 2019";
    ZoneId preferredZone = ZoneId.of("Europe/London");
    DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
            .appendPattern("EEE MMM dd HH:mm:ss ")
            .appendZoneText(TextStyle.SHORT, Collections.singleton(preferredZone))
            .appendPattern(" yyyy")
            .toFormatter(Locale.ROOT);
    ZonedDateTime zd = ZonedDateTime.parse(sTime, FORMATTER);
    System.out.println("The time zone: " + zd.getZone());
    FileTime ftReturn = FileTime.from(zd.toEpochSecond(), TimeUnit.SECONDS);
    System.out.println("File time is: " + ftReturn);

Вывод:

The time zone: Europe/London
File time is: 2019-06-07T13:07:07Z

Ссылки

...