Как установить EET для даты в Java?

У меня есть код, который преобразует String в Date на Java следующим образом:

String value = "20220307150417";
DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
Date date = formatter.parse(value);
System.out.println(date.toString());

Но вывод такой: Mon Mar 07 15:04:17 EEST 2022

Как я могу изменить это на EET? Поэтому я хочу, чтобы ответ был Mon Mar 07 15:04:17 EET 2022.

Прекратите использовать SimpleDateFormat, переключитесь на более продвинутые пакеты java.time и их средство форматирования.

Mark Rotteveel 11.05.2023 11:54

Также прочтите codeblog.jonsket.uk/2017/04/23/all-about-java-util-date, чтобы знать, из чего на самом деле состоит java.util.Date. (В частности, см. «Общие вопросы» внизу поста.)

Jon Skeet 11.05.2023 11:57

Мне нужно использовать Date, или я могу использовать LocalDateTime, а затем преобразовать в Date.

elvis 11.05.2023 12:00

Ни Date, ни LocalDateTime не могут иметь часовой пояс (или аббревиатуру часового пояса). Вы просите невозможного.

Ole V.V. 11.05.2023 12:38

Если я правильно понял, в Ливии (несмотря на то, что она находится в Африке) весь год используется восточноевропейское время (без летнего/летнего времени). Итак, LocalDateTime.parse(value, DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ROOT)) .atZone(ZoneId.of("Africa/Tripoli")) .format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LO‌​NG)) в зависимости от локали дает 7 March 2022 at 15:04:17 EET. Однако не уверен, что это то, что вам нужно и чего вы хотите.

Ole V.V. 11.05.2023 12:48
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
5
82
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Оба класса SimpleDateFormat и Date устарели (каламбур). Эта модель представления дат имеет серьезные недостатки, и даже до того, как java придумала замену, были другие библиотеки, которые предлагали лучшие решения. Однако к настоящему времени вы должны использовать пакет java.time. В вашем случае найдите классы DateTimeFormatter и ZonedDateTime. Читайте также о пакете java.time.

Также вам может быть актуально: Однажды у меня был проект, в котором мне нужно было разобрать строку, которая может соответствовать любому возможному формату для даты, не зная формата. Итак, мне пришла в голову идея, что я сохранил все поддерживаемые форматы в файле свойств и попытался проанализировать строку со всеми этими форматами один за другим до успеха или до тех пор, пока все форматы не сработали. Интересно отметить, что в этом случае порядок форматов списка также может быть важен, поскольку дата, такая как 03-02-2022, может быть проанализирована как 2 марта или 3 февраля в зависимости от американского или европейского стиля. В любом случае я написал статью об этой идее, которая может быть актуальна здесь: Пакет Java 8 java.time: разбор любой строки на сегодняшний день

Ответ принят как подходящий

Вы можете преобразовать String в LocalDateTime (только дата и время суток, БЕЗ зоны и БЕЗ смещения от UTC/GMT).
Если вы впоследствии примените определенную зону, вы можете создать ZonedDateTime, который можно отформатировать по желанию.

ZonedDateTime можно преобразовать в Instant, и это вариант для устаревшей совместимости, потому что есть Date.from(Instant) и Date.toInstant().

Вот пример с разными выводами

public static void main(String[] args) {
    // example input
    String value = "20230607121201";
    // create a formatter for parsing the String
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMddHHmmss");
    // parse the String to a 
    LocalDateTime localDateTime = LocalDateTime.parse(value, dtf);
    // create the desired zone id
    ZoneId zoneId = ZoneId.of("Europe/Kaliningrad");
    // compose the LocalDateTime and the ZoneId
    ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
    // create a formatter with the same format as Date.toString()
    DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern(
                                "EEE MMM dd HH:mm:ss z uuuu",
                                Locale.ENGLISH);
    // get the Instant
    Instant instant = zonedDateTime.toInstant();
    // create a Date from the Instant
    Date date = Date.from(instant);
    // print the different representations
    System.out.println("ZonedDateTime.format(): " + zonedDateTime.format(dtfOut));
    System.out.println("Instant.toEpochMilli(): " + instant.toEpochMilli());
    System.out.println("Date.getTime():         " + date.getTime());
    System.out.println("Date.toString():        " + date);
}

Обратите внимание, что Date.toString() учитывает языковой стандарт системы и часовой пояс, очевидно, не зная о переходе на летнее время.

Это заняло мой Locale

Выход

ZonedDateTime.format(): Wed Jun 07 12:12:01 EET 2023
Instant.toEpochMilli(): 1686132721000
Date.getTime():         1686132721000
Date.toString():        Wed Jun 07 12:12:01 CEST 2023

Обратите внимание, что и Instant.toEpochMilli(), и Date.getTime() имеют одинаковое значение эпохи в миллисекундах!


Почему ZoneId.of("Europe/Kaliningrad")?

Потому что кажется, что требование всегда использовать EET. Это означает, что вы должны выбрать идентификатор зоны, который

  • находится в / использует EET
  • не применяется летнее время

Спасибо за объяснение. Я вижу, что он работает правильно, но для некоторых значений он показывает EEST. Например, если вы попробуете ввести 20230607121201, ответ будет следующим: среда, 07 июня, 12:12:01, восточноевропейское восточное время 2023. Что я могу сделать, чтобы работать со всеми значениями?

elvis 11.05.2023 16:09

Привет! Вам понадобится идентификатор зоны, который (1.) использует EET и (2.) не применяет летнее время, поэтому измените код на использование ZoneId zoneId = ZoneId.of("Europe/Kaliningrad");. Румыния, похоже, применяет летнее время, а российский эксклав - нет.

deHaar 11.05.2023 16:18

Другие вопросы по теме