Dateformatter в java [дубликат]



На этот вопрос уже есть ответ здесь:



Я использую приведенный ниже код для форматирования строк даты разрешения миллисекунды. Он работает для 2018-09-14T13:05:21.329Z, но не для 2018-09-14T13:05:21.3Z. Может ли кто-нибудь подсказать причину и как ее исправить?



DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date parsedDate = formatter.parse(date);
String destDate = sdfDestination.format(parsedDate);
return destDate;
} catch (java.text.ParseException parseException) {
logger.error("Parse Exception occured while converting publication time to date "
+ "format 'yyyy-MM-dd HH:mm:ss'", parseException);
}


Я получаю ниже исключение:



java.text.ParseException: Unparseable date: "2018-09-14T13:05:21.3Z"
at java.text.DateFormat.parse(Unknown Source) ~[na:1.8.0_181]
at com.noordpool.api.implementation.utility.Utility.parseDate(Utility.java:136) [classes/:na]
at com.noordpool.api.implementation.utility.Utility.parseMessage(Utility.java:77) [classes/:na]
660   4  

4 ответов:

Ваша единственная проблема заключается в том, что вы используете неправильный шаблон для SimpleDateFormat, вам нужно изменить:

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");

Кому:

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

Потому что Z, используемый в строке date, означает "смещение нулевого часа", поэтому вам просто нужно передать его как 'Z' в вашем шаблоне.

Это рабочая демонстрация с правильным рисунком.

Редактировать:

И чтобы заставить вещи работать с различными локалями и часовыми поясами, вам нужно использовать соответствующие Locale Когда вы создаете экземпляр SimpleDateFormat, Вот каким должен быть код:

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);

Единственная возможная проблема, которую я вижу, заключается в том, что вы неправильно передаете миллисекунды, и программа не знает, что с этим делать.

Таким образом, последняя часть форматера указывает с миллисекундами и часовым поясом как .SSSX

Но как он оценивает 3Z для входа в это? Я имею в виду, вы говорите, что это 300 часовой пояс Z, или говорите, что это 003 часовой пояс Z, или еще хуже, попробуйте разобрать его как 3Z, что, надеюсь, вы видите, что вы не можете превратить " 3Z " в число.

Чтобы исправить это, Я бы проверил ваш ввод "дата" и убедился, что часть миллисекунд всегда состоит из 3 цифр, это устраняет двусмысленность, и программа всегда знает, что вы имеете в виду "300 миллисекунд, часовой пояс Z".

Существует проблема в java 8, где количество символов, которые вы указали с помощью форматера, должно точно совпадать (что не указано в документации). Вы можете использовать три различных Формататора и использовать вложенное исключение следующим образом:

DateFormat format1 = new SimpleDateFormat("y-M-d'T'H:m:s.SX");
DateFormat format2 = new SimpleDateFormat("y-M-d'T'H:m:s.SSX");
DateFormat format3 = new SimpleDateFormat("y-M-d'T'H:m:s.SSSX");
Date parsedDate;

try {
    // Parsing for the case - 2018-09-14T13:05:21.3Z 
    parsedDate  = format1.parse(date); 
} catch (ParseException e1) {

    try {
         // Parsing for the case - 2018-09-14T13:05:21.32Z 
         parsedDate = format2.parse(date); 
    } catch (ParseException e2) {

          try {
              // Parsing for the case - 2018-09-14T13:05:21.329Z 
              parsedDate = format3.parse(date);
          } catch (ParseException e2) {
             //The input date format is wrong
             logger.error("Wrong format for date - " + date);      
          }

    }
}

[12]}Java.время

    DateTimeFormatter dtfDestination
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    String date = "2018-09-14T13:05:21.3Z";
    String destDate = Instant.parse(date)
            .atZone(ZoneId.of("Indian/Comoro"))
            .format(dtfDestination);
    System.out.println(destDate);

Выходные данные этого фрагмента:

2018-09-14 16:05:21

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

Я эксплуатирую дело в том, что ваша строка, "2018-09-14T13:05:21.3Z", находится в формате ISO 8601, формате, который используют классы java.time parse по умолчанию, то есть без явного форматирования. Instant.parse принимает что-либо от 0 до 9 десятичных знаков на секундах, так что нет никаких проблем, давая ему строку только с 1 десятичной, как вы сделали. В сравнении с этим нет способа, которым старомодный SimpleDateFormat может разобрать 1 десятичный знак на секундах с полной точностью, так как он принимает букву шаблона (верхний регистр) S, чтобы означать миллисекунды, так что .3 будет проанализировано как 3 миллисекунды, а не 3 десятых секунды, как это означает.

Jahnavi Paliwal уже правильно поставил диагноз и объяснил причину полученного вами исключения.

Классы даты и времени, которые вы использовали, DateFormat, SimpleDateFormat и Date, все они давно устарели и SimpleDateFormat в особенности печально известны. Поскольку вы, кажется, используете Java 8 (и даже если вы этого не сделали), я предлагаю вам полностью избегать этих классов и использовать java.время вместо.

Ссылки

Comments

    Ничего не найдено.