Как преобразовать дату UTC в местную дату в Java 1.6 - PullRequest
0 голосов
/ 24 мая 2019

Я получаю строку с меткой времени UTC из XML-файла, например, так:

2019-05-24T00:59:55.1-05:00

Я преобразую строку в дату с помощью метода ниже.

    private Date getUTC2JavaDateB(String dateStr) {
    String dateS = dateStr;
    String timePattern = "";
    Date d = null;
    SimpleDateFormat formatter = null;
    if (dateS.length() >= 19) {
        dateS = dateS.substring(0, 19);
    }
    timePattern = "yyyy-MM-dd'T'hh:mm:ss";
    formatter = new SimpleDateFormat(timePattern);
    d = formatter.parse(dateS, new ParsePosition(0));

    return d;
}

Теперь здесьэто моя проблемаЯ хочу преобразовать его из UTC в местное время.

Я нашел некоторые фрагменты кода в некоторых других потоках, но они еще не работают для меня.

    private Date toLocalTimeStamp(Date date) {
    try {

        DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

        DateFormat currentTFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        currentTFormat.setTimeZone(TimeZone.getTimeZone(getCurrentTimeZone()));

        return currentTFormat.format(date);
    } catch (Exception ex) {
        return date;
    }
}

Я получаю исключение "Строкане может быть преобразовано в дату "- что для меня ясно.Но как мне теперь преобразовать строку в дату?И мой метод преобразования UTC в местную дату правильный?

Любая помощь очень ценится!: -)

Ответы [ 3 ]

1 голос
/ 24 мая 2019

ThreeTen Backport

import org.threeten.bp.OffsetDateTime;
import org.threeten.bp.ZoneId;
import org.threeten.bp.ZonedDateTime;

public class ConvertUtcDateTimeToLocalInJava16 {

    public static void main(String[] args) {
        String dateStr = "2019-05-24T00:59:55.1-05:00";
        OffsetDateTime dateTime = OffsetDateTime.parse(dateStr);
        ZonedDateTime dateTimeInMyTimeZone
                = dateTime.atZoneSameInstant(ZoneId.systemDefault());
        System.out.println(dateTimeInMyTimeZone);
    }

}

Я запустил эту программу на Java 1.7.0_67.Вывод:

2019-05-24T07: 59: 55.100 + 02: 00 [Европа / Копенгаген]

Я не установил Java 1.6 самостоятельно,но запуск программы по крайней мере доказывает, что ей не нужна Java 1.8.Смею утверждать, что он будет работать и на вашей Java 1.6.Вам просто нужно добавить ThreeTen Backport в ваш проект.Используйте ссылку внизу.

ThreeTen Backport - это бэкпорт java.time, современного API даты и времени Java, для Java 6 и 7.

Я использую тот факт, что вашстрока даты и времени в формате ISO 8601, формат, который классы из java.time анализируют (и также печатают) по умолчанию.Как вы, возможно, знаете, -05:00 в конце вашей строки - это смещение UTC, означающее 5 часов после UTC (поэтому ваше время 00: 59: 55.1 соответствует 05: 59: 55.1 UTC).

Даже на Java 1.6 вам не нужно использовать Date и SimpleDateFormat.Эти классы всегда были плохо спроектированы, в частности, последние, как известно, доставляют неприятности.Поэтому не используйте их.

Укажите часовой пояс, если вы можете

ZoneId.systemDefault() дает вам настройку часового пояса JVM.Это должен быть «местный часовой пояс», о котором вы просили, но он хрупкий, поскольку параметр может быть изменен другой частью вашей программы или любой другой программой, работающей в той же JVM, в любое время.Если у вас есть способ узнать правильный часовой пояс, лучше указать его явно.Например:

    ZonedDateTime dateTimeInMyTimeZone
            = dateTime.atZoneSameInstant(ZoneId.of("Africa/Algiers"));

2019-05-24T06: 59: 55.100 + 01:00 [Африка / Алжир]

Что для вас пошло не так?

Сначала я подозреваю, что ваши ожидания неверны.Оба ваших метода преобразования возвращают Date, но Date не может иметь часовой пояс, так что это будет бесполезно.Date - это момент времени, ни больше, ни меньше.В отличие от Date java.time предлагает OffsetDateTime, дату и время со смещением UTC, и ZonedDateTime, дату и время с часовым поясом.

Строчные hh в вашем форматестрока шаблона неверна.Это час в течение AM или PM с 01 по 12. Час в вашей строке указан на 24-часовых часах, с 00 до 23. Для этого вам понадобится прописная буква HH, как и во втором методе.

Далее вы не анализируете смещение UTC от вашей строки, таким образом, вероятно, получая неправильное время (SimpleDateFormat использует ваш часовой пояс по умолчанию в этом случае).То, что вы также игнорируете десятичную дробь (.1 в вашем примере), является деталью, вносящей ошибку менее секунды.В любом случае SimpleDateFormat не может правильно проанализировать один десятичный знак в секундах (он поддерживает только три десятичных знака).

Links

0 голосов
/ 24 мая 2019

Если вы застряли на Java 6 и не имеете более новой библиотеки обработки времени (Joda Time, 310 backport, ...) ...

Использование методов обработки дат в XML

Дата, которую вы пытаетесь проанализировать, отформатирована в формате ISO-8601, и именно это использует тип данных XML DateTime.

Java 6 поставляется с реализациями JAXB, которые предоставляют множество инструментов для обработки XML, включая анализ типов дат ISO 8601. Особый интерес здесь представляет GregorianXMLCalendar

Так что это даст вам java.util.Date:

java.util.Date date = DatatypeFactory.newInstance()
  .newXMLGregorianCalendar("2019-05-24T00:59:55.1-05:00")
  .toGregorianCalendar()
  .getTime()

То, что вы затем сможете отображать и форматировать в своей зоне интереса ...

    // What is the UTC hour of 00:59:55.1 at -5 offset ?
    SimpleDateFormat utc = new SimpleDateFormat("HH:mm");
    utc.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println(utc.format(date)); // --> 05:59

    // What would it be in Paris ?
    SimpleDateFormat paris = new SimpleDateFormat("HH:mm");
    paris.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
    System.out.println(paris.format(date)); // -> 07:59 Paris is UTC+2 in the summer, so it's OK.
0 голосов
/ 24 мая 2019

В вашей строке уже есть индикатор часового пояса. Если по какой-то причине вы застряли с Java 6 (см. мой комментарий ), вы можете легко обновить строку, а затем проанализировать ее полностью, включая часовой пояс, с помощью SimpleDateFormat * * 1006

// Remove the colon in the timezone indicator
assert str.charAt(str.length() - 3) == ':';
str = str.substring(0, str.length() - 3) + str.substring(str.length() - 2);
// Parse the result
Date dt = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).parse(str);

Живой пример

...