Что это за формат даты? 2011-08-12T20: 17: 46.384Z

У меня есть следующая дата: 2011-08-12T20:17:46.384Z. Какой формат это? Я пытаюсь разобрать его с помощью Java 1.4 через DateFormat.getDateInstance().parse(dateStr), и я получаю

java.text.ParseException: Непревзойденная дата: "2011-08-12T20: 17: 46.384Z"

Я думаю, что я должен использовать SimpleDateFormat для синтаксического анализа, но сначала я должен знать строку формата. Все, что у меня для этого пока есть yyyy-MM-dd, потому что я не знаю, что означает T в этой строке - что-то связанное с часовым поясом? Эта строка даты исходит от тега lcmis:downloadedOn, показанного на Файлы CMIS для загрузки типа носителя истории.

Ответ 1

Буква T - это просто литерал для ветки даты от времени, а буква Z означает "смещение нулевого часа", также известное как "время Зулу" (UTC). Если ваши строки всегда имеют "Z", вы можете использовать:

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

Или используя Joda Time, вы можете использовать ISODateTimeFormat.dateTime().

Ответ 2

ТЛ; др

В качестве входной строки используется стандартный формат ISO 8601.

Instant.parse ( "2011-08-12T20:17:46.384Z" ) 

ISO 8601

Этот формат определяется разумным практическим стандартом ISO 8601.

T отделяет часть даты от части времени суток. Z на конце означает UTC (то есть смещение от UTC, равное нулю часов, минут и секунд). Z произносится как "зулу".

java.time

Старые классы даты и времени, включенные в ранние версии Java, оказались плохо спроектированными, запутанными и хлопотными. Избегайте их.

Вместо этого используйте платформу java.time, встроенную в Java 8 и более поздние версии. Классы java.time вытесняют как старые классы даты и времени, так и очень успешную библиотеку Joda-Time.

Классы java.time по умолчанию используют ISO 8601 при анализе/генерации текстовых представлений значений даты и времени.

Класс Instant представляет момент на временной шкале в UTC с разрешением наносекунд. Этот класс может напрямую анализировать вашу входную строку, не заботясь об определении шаблона форматирования.

Instant instant = Instant.parse ( "2011-08-12T20:17:46.384Z" ) ;

Table of date-time types in Java, both modern and legacy


О java.time

Среда java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time, который теперь находится в режиме обслуживания, рекомендует выполнить переход на классы java.time.

Чтобы узнать больше, см. Учебное пособие по Oracle. И поищите в Кару множество примеров и объяснений. Спецификация: JSR 310.

Где взять классы java.time?

  • Java SE 8, Java SE 9 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые мелкие функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 & 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP....

Table of which java.time library to use with which version of Java or Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и еще.

Ответ 4

Есть и другие способы анализа, а не первый ответ. Чтобы проанализировать его:

(1) Если вы хотите получить информацию о дате и времени, вы можете проанализировать ее на объект ZonedDatetime (начиная с Java 8) или Date (старый):

// ZonedDateTime default format requires a zone ID(like [Australia/Sydney]) in the end.
// Here, we provide a format which can parse the string correctly.
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
ZonedDateTime zdt = ZonedDateTime.parse("2011-08-12T20:17:46.384Z", dtf);

или же

// 'T' is a literal.
// 'X' is ISO Zone Offset[like +01, -08]; For UTC, it is interpreted as 'Z'(Zero) literal.
String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX";

// since no built-in format, we provides pattern directly.
DateFormat df = new SimpleDateFormat(pattern);

Date myDate = df.parse("2011-08-12T20:17:46.384Z");

(2) Если вам не нужны дата и время и просто хотите обрабатывать информацию как момент в наносекундах, вы можете использовать Instant:

// The ISO format without zone ID is Instant default.
// There is no need to pass any format.
Instant ins = Instant.parse("2011-08-12T20:17:46.384Z");

Ответ 5

Вы можете использовать следующий пример.

    String date = "2011-08-12T20:17:46.384Z";

    String inputPattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    String outputPattern = "yyyy-MM-dd HH:mm:ss";

    LocalDateTime inputDate = null;
    String outputDate = null;


    DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(inputPattern, Locale.ENGLISH);
    DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(outputPattern, Locale.ENGLISH);

    inputDate = LocalDateTime.parse(date, inputFormatter);
    outputDate = outputFormatter.format(inputDate);

    System.out.println("inputDate: " + inputDate);
    System.out.println("outputDate: " + outputDate);

Ответ 6

На самом деле это формат строки даты ISO. Вы можете достичь этого следующим образом:

new Date().toISOString();
//output : "2019-04-17T17:17:49.618Z"

1. "2019-04-17": очевидно, как вы видите, эта часть является ДАТА.

2. "17: 17: 49.618": и эта часть - ВРЕМЯ.

3. "T": и буква "T", которая находится в позиции между датой и временем, является просто литералом, отделяющим дату от времени.

3. "Z": "Z" - самая любопытная часть этого формата. Z обозначает часовой пояс Зулу (UTC). который расположен по смещению 0:00 UTC. это также называется "НОЛЬ".

Ответ 7

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

public static long timestampToEpochSeconds(String srcTimestamp) {
    long epoch = 0;

    try {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Instant instant = Instant.parse(srcTimestamp);
            epoch = instant.getEpochSecond();
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'", Locale.getDefault());
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date date = sdf.parse(srcTimestamp);
            if (date != null) {
                epoch = date.getTime() / 1000;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return epoch;
}

Пример ввода: 2019-10-15T05: 51: 31.537979Z

Пример вывода: 1571128673

Ответ 8

Этот метод переводит java.util.Date в формат UTC (или любой другой) и обратно.

Определите класс следующим образом:

import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class UtcUtility {

public static DateTimeFormatter UTC = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZoneUTC();


public static Date parse(DateTimeFormatter dateTimeFormatter, String date) {
    return dateTimeFormatter.parseDateTime(date).toDate();
}

public static String format(DateTimeFormatter dateTimeFormatter, Date date) {
    return format(dateTimeFormatter, date.getTime());
}

private static String format(DateTimeFormatter dateTimeFormatter, long timeInMillis) {
    DateTime dateTime = new DateTime(timeInMillis);
    String formattedString = dateTimeFormatter.print(dateTime);
    return formattedString;
}

}

Тогда используйте это так:

Date date = format(UTC, "2020-04-19T00:30:07.000Z")

или же

String date = parse(UTC, new Date())

Вы также можете определить другие форматы даты, если вам требуется (не только UTC)

Ответ 9

@Джон-Скит дал мне подсказку, чтобы решить мою проблему вокруг этого. Будучи молодым программистом, эту маленькую проблему легко упустить и ее трудно диагностировать. Так что я делюсь этим в надежде, что это кому-нибудь поможет.

Моя проблема заключалась в том, что я хотел проанализировать следующую строку, противоречащую отметке времени из JSON, на которую я не имею никакого влияния, и поместить ее в более полезные переменные. Но я продолжал получать ошибки.

Поэтому, учитывая следующее (обратите внимание на строковый параметр внутри ofPattern();

String str = "20190927T182730.000Z"

LocalDateTime fin;
fin = LocalDateTime.parse( str, DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss.SSSZ") );

Ошибка:

Exception in thread "main" java.time.format.DateTimeParseException: Text 
'20190927T182730.000Z' could not be parsed at index 19

Проблема? Буква Z в конце шаблона должна быть заключена в букву "Z", как и буква "T". + Изменить "yyyyMMdd'T'HHmmss.SSSZ" - "yyyyMMdd'T'HHmmss.SSS'Z'" и это работает.

Удаление Z из шаблона в целом также привело к ошибкам.

Честно говоря, я ожидал бы, что класс Java предвидит это.

Ответ 10

Самый простой способ решить эту проблему - заменить "T" на " " и удалить .384Z.

Ниже приведена иллюстрация того, как достичь этого:

public static String getTime(String time) {
    if (time != null) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        if (time.toUpperCase().contains("T") && time.toUpperCase().contains("Z")) {
            time = time.toUpperCase().replace("T", " ");
            String[] str = time.split("\\.");

            if (str.length != 0) {
                return str[0];
            }
        }

        try {
            Date date = new Date(time);
            time = simpleDateFormat.format(date);
        } catch (Exception e) {
        //
        }
    }
    return time;
}