Java SimpleDateFormat не определяет месяц

Я использую SimpleDateFormat в Java, и по какой-то причине он не определяет месяц. Вот мой код:

     /**
     * Takes a date/time stamp which looks like yyyyMMDDhhmmss on converts it to
     * yyyy-MM-DDThh:mm:ssZ
     *
     * @param timestamp
     * @return
     */
    public static String ConvertDate(String timestamp) {
        if (timestamp == null || timestamp.length() < 14)
            return null;

        String timeString = null;

        System.out.println(timestamp);
        DateFormat outputFormat = new SimpleDateFormat("YYYY-MM-DD'T'hh:mm:ss'Z'");
        DateFormat inputFormat = new SimpleDateFormat("yyyyMMDDhhmmss");

        try{
            Date date = inputFormat.parse(timestamp);
            timeString = outputFormat.format(date);
        }
        catch(Exception e){}

        return timeString;
    }

Вызов этого метода: ConvertDate("20190803122424") возвращает следующее: 2019-01-03T12:24:24Z тогда как я хочу вернуть: 2019-08-03T12:24:24Z

Что-то не так с моим форматом вывода?


person Smi28    schedule 12.11.2019    source источник
comment
Вы пытались изменить yyyyMMDDhhmmss на yyyyMMddHHmmss (нижний регистр D, верхний регистр H)?   -  person BBacon    schedule 12.11.2019
comment
Стоит отметить, что в этом случае вызов setLenient(false) приводит к тому, что parse выдает исключение.   -  person Ian McLaird    schedule 12.11.2019
comment
Я рекомендую вам не использовать SimpleDateFormat и Date. Эти классы плохо спроектированы и давно устарели, а первые, как известно, доставляют много хлопот. Вместо этого используйте OffsetDateTime и DateTimeFormatter из java.time, современного API даты и времени Java.   -  person Ole V.V.    schedule 12.11.2019
comment
Не только ваш входной формат, ваша строка шаблона выходного формата также имеет пару экземпляров неправильного регистра букв шаблона. Кроме того, 'Z' с кавычками обязательно даст вам неправильные результаты.   -  person Ole V.V.    schedule 12.11.2019


Ответы (2)


Вы используете неправильную строку формата даты: DD (день в году) вместо dd (день в месяце). Измените оба экземпляра SimpleDateFormat на использование dd:

DateFormat inputFormat = new SimpleDateFormat("yyyyMMddhhmmss");
DateFormat outputFormat = new SimpleDateFormat("YYYY-MM-dd'T'hh:mm:ss'Z'");

Поэтому вы получаете неверный результат.

person Robert    schedule 12.11.2019
comment
отдай дьяволу должное, ты быстрее - person snr; 12.11.2019
comment
Это вернуло правильный месяц, но испортило день: 2019-08-215T12:24:24Z - person Smi28; 12.11.2019
comment
@ Smi28 Smi28 Это проблема средства форматирования вывода, а не анализатора даты. - person Robert; 12.11.2019
comment
Вы также использовали DD в средстве форматирования вывода. Вам нужно dd в обоих случаях. - person Ian McLaird; 12.11.2019

Как все указывали, ваш форматер yyyyMMDDhhmmss неверен, поэтому создайте DateTimeFormatter с допустимым форматом

DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

И с помощью API даты и времени java-8 проанализируйте его в LocalDateTime, а затем в формат UTC, используя ZonedDateTime

String dateString = "20190803122424";

LocalDateTime localDateTime = LocalDateTime.parse(dateString,inputFormat);

И тогда вы можете преобразовать его в OffsetDateTime

 OffsetDateTime outputDateTime = localDateTime.atOffset(ZoneOffset.UTC);

В случае, если вы особенно хотите ZonedDateTime

ZonedDateTime outputDateTime = localDateTime.atZone(ZoneOffset.UTC);
person Deadpool    schedule 12.11.2019
comment
Спасибо, я обновил подход к использованию OffsetDateTime @BasilBourque. - person Deadpool; 12.11.2019
comment
Спасибо за мысль, но не нужно благодарить меня. Я предлагаю полностью заменить вашу строку ZonedDateTime на OffsetDateTime. Кроме того, я предлагаю разбить ваш объект LocalDateTime на отдельную строку для ясности. Итак, две строки: LocalDateTime localDateTime = … и OffsetDateTime offsetDateTime = …. - person Basil Bourque; 12.11.2019