GMT + преобразование строки в дату Java

Я пытаюсь преобразовать строку в формате «среда, 01 июня, 00:00:00 GMT-400 2016» в ISO8601 «2016-06-01T00: 00: 00.000Z». Я получаю сообщение об ошибке «Дата не поддается анализу». Я не уверен, что делаю не так.

    DateFormat startDate = new SimpleDateFormat("EEE MMM dd HH:mm:ss 'GMT'Z yyyy", Locale.US);
    startDate.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US);
    formatter.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

    Date aParsedDate = null;
    try {
        // give the date in that format
        aParsedDate = (Date) startDate.parse(inputDateAsString);
        System.out.println(aParsedDate.toString());

        // convert Date to ISO8601
        String nowAsISO = formatter.format(aParsedDate);
        System.out.println("ISO date = " + nowAsISO);
        return nowAsISO;

    } catch (ParseException e) {
        e.printStackTrace();
    }

person Annie    schedule 04.07.2016    source источник
comment
Проблема в смещении - Z ожидает что-то вроде -0400, а вы передаете -400. Я не думаю, что есть простой способ разобрать его без предварительного изменения входной строки. z (нижний регистр) принимает общий формат часового пояса, который не требует ведущего 0, но требует : между часами и минутами ...   -  person assylias    schedule 04.07.2016
comment
Пожалуйста, не используйте Date, Calendar и SimpleDateFormat, они устарели и проблематичны. Вот почему. Используйте классы из java.time. См. Опубликованный ответ для получения более подробной информации.   -  person MC Emperor    schedule 16.05.2021


Ответы (1)


java.time

Стандарт ISO 8601 для смещения часового пояса представляет ЧАС двумя цифрами. Разделитель для ЧАСА и МИНУТ не является обязательным. МИНУТА также является необязательной, если она равна нулю. Однако в строке даты и времени среда, 01 июня, 00:00:00 GMT-400 2016 ЧАС состоит только из одной цифры.

Нет OOTB (Out-Of-The-Box) _ 1_, определенный для шаблона, в котором указана ваша строка даты и времени, среда, 01 июня, 00:00:00 GMT-400 2016. К счастью, java.time, современный API даты и времени предоставляет вам способ определять / создавать типы синтаксического анализа / форматирования со сложными шаблонами.

Демо:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .appendPattern("E MMM d H:m:s")
                                .appendLiteral(' ')
                                .appendZoneId()
                                .appendOffset("+Hmm", "")
                                .appendLiteral(' ')
                                .appendPattern("u")
                                .toFormatter(Locale.ENGLISH);
                                
        String strDateTime = "Wed Jun 01 00:00:00 GMT-400 2016";
        
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime, dtf);
        System.out.println(odt);
    }
}

Вывод:

2016-06-01T00:00-04:00

Как видите, для смещения часового пояса я использовал шаблон +Hmm (одна цифра для ЧАСА и две для МИНУТЫ).

Узнайте больше о современном API даты и времени на странице Trail: Date Time < / а>.

Обратите внимание, что устаревший API даты и времени (java.util типы даты и времени и их тип форматирования, SimpleDateFormat) устарел и подвержен ошибкам. Рекомендуется полностью прекратить его использование и перейти на java.time, современный API даты и времени *.

По какой-либо причине, если вам нужно преобразовать этот объект OffsetDateTime в объект java.util.Date, вы можете сделать это следующим образом:

Date date = Date.from(odt.toInstant());

* По любой причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который поддерживает большую часть функций java.time для Java 6 и 7. Если вы работаете над проектом Android и ваш уровень API Android по-прежнему не соответствует Java-8, проверьте API Java 8+ доступно через удаление сахара и Как использовать ThreeTenABP в Android Project.

person Arvind Kumar Avinash    schedule 16.05.2021