Что это за формат даты? 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?
![Table of which java.time library to use with which version of Java or Android]()
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и еще.
Ответ 3
Не уверен в синтаксическом анализе Java, но это ISO8601: http://en.wikipedia.org/wiki/ISO_8601
Ответ 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;
}