Вывод метки времени RFC 3339 в Java

Я хочу вывести метку времени со смещением PST (например, 2008-11-13T13: 23: 30-08: 00). java.util.SimpleDateFormat, похоже, не выводит смещения часовых поясов в формате час: минута, он исключает двоеточие. Есть ли простой способ получить эту метку времени в Java?

// I want 2008-11-13T12:23:30-08:00
String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").format(new Date());
System.out.println(timestamp); 
// prints "2008-11-13T12:23:30-0800" See the difference?

Кроме того, SimpleDateFormat не может правильно проанализировать приведенный выше пример. Кидает ParseException.

// Throws a ParseException
new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").parse("2008-11-13T13:23:30-08:00")
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
41
0
47 379
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");

Разве не то, что вам нужно?

Нет. Если вы попытаетесь проанализировать указанную выше метку времени, она выдаст исключение ParseException.

Cristian 19.11.2008 07:11

Ознакомьтесь с пакетом Джода Тайм. Они значительно упрощают форматирование даты RFC 3339.

Пример Джоды:

DateTime dt = new DateTime(2011,1,2,12,45,0,0, DateTimeZone.UTC);
DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
String outRfc = fmt.print(dt);

Этот ответ был бы полезен на примере.

noah 24.01.2011 00:35

@Biff Вы можете упростить пример кода. Нет необходимости в форматировщике. Joda-Time автоматически по умолчанию использует формат ISO 8601 / RFC 3339. Просто вызовите метод toString явно или неявно. Вот так, String output = dt.toString();

Basil Bourque 31.03.2014 18:18

Проблема в том, что Z производит смещение часового пояса без двоеточия (:) в качестве разделителя.

Абсолютно верно, но не говорит нам, как это исправить. Решение от jjohn исправило это для меня.

scaganoff 13.11.2013 15:11

Одно из решений из раздела «Сделай это» - использовать регулярные выражения для исправления строки после завершения SimpleDateFormat. Что-то вроде s / (\ d {2}) (\ d {2}) $ / $ 1: $ 2 / в Perl.

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

Но да. Я тоже сталкиваюсь с этой проблемой. RFC3339, я на тебя смотрю!

Обновлено:

Это работает для меня

// As a private class member
private SimpleDateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

String toRFC3339(Date d)
{
   return rfc3339.format(d).replaceAll("(\\d\\d)(\\d\\d)$", "$1:$2");
}

Я нашел случайный PasteBin, который помог мне с проблемой: http://pastebin.com/y3TCAikc

На всякий случай, если его содержимое позже будет удалено:

// I want 2008-11-13T12:23:30-08:00
String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").format(new Date());
System.out.println(timestamp); 
// prints "2008-11-13T12:23:30-0800" See the difference?

// Throws a ParseException
new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").parse("2008-11-13T13:23:30-08:00")

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");

Я сделал класс Интернет-формат для RFC3339.

Но комментарий к исходному коду - японский.

PS: Я создал английскую версию и немного поработал.

Ответ принят как подходящий

Начиная с Java 7, есть строка шаблона X для часового пояса ISO8601. Для строк в описываемом вами формате используйте XXX. См. Документацию.

Образец:

System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
        .format(new Date()));

Результат:

2014-03-31T14:11:29+02:00

Я получаю исключение ParseException при разборе "2017-12-12T02: 01: 43.924-08: 00", которое я получил из API Google Cloud.

pujan jain 18.12.2017 14:56

@pujanjain У этого есть миллисекунды, которые этот шаблон не включает.

Daniel Beck 18.12.2017 20:37

Я бы сказал, что любой ответ, который утверждает, что он соответствует RFC3339, должен указывать на необязательную 1-значную миллисекунду в соответствии с xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14

Marcel Stör 27.04.2018 18:27

Я потратил довольно много времени на поиски ответа на ту же проблему и кое-что нашел здесь: http://developer.android.com/reference/java/text/SimpleDateFormat.html

Предлагаемый ответ:

String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZZZZZ").format(new Date());

Если вы заметили, я использую 5 Z вместо одной. Это дает результат с двоеточием в смещении, например: «2008-11-13T12: 23: 30-08: 00». Надеюсь, это поможет.

Спасибо - ваш ответ недооценен - ​​это то, что наконец позволило мне вывести RFC 3339. Использование X дало мне Caused by: java.lang.IllegalArgumentException: Illegal pattern component: XXX at org.apache.commons.lang.time.FastDateFormat.parsePattern(Fas‌​tDateFormat.java:691‌​) at org.apache.commons.lang.time.FastDateFormat.init(FastDateFor‌​mat.java:558)

Zasz 15.01.2017 22:03

Рад помочь :)

Rahul Ravindran 06.06.2017 14:11

Мы можем просто использовать для этого ZonedDateTime класс и DateTimeFormatter класс.

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
ZonedDateTime z2 = ZonedDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.SECONDS);
System.out.println("format =======> " + z2.format(format));

Вывод: формат =======> 30-03-2020T05: 57: 37 + 00: 00

Другие вопросы по теме