Как получить текущий момент в формате ISO 8601 с датой, часом и минутой?

Какой самый элегантный способ получить форматирование в формате ISO 8601 текущего момента, UTC? Это должно выглядеть так: 2010-10-12T08:50Z.

Пример:

String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);

Ответ 1

Используйте SimpleDateFormat для форматирования любого Date объект, который вы хотите:

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

Используя new Date(), как показано выше, отформатируйте текущее время.

Ответ 2

Для систем, где часовой пояс по умолчанию не является UTC:

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

Экземпляр SimpleDateFormat может быть объявлен как глобальная константа при необходимости часто, но будьте осторожны, чтобы этот класс не был потокобезопасным. Он должен быть синхронизирован при одновременном доступе несколькими потоками.

EDIT: я бы предпочел Joda Time, если бы делал много разных манипуляций Times/Date...
EDIT2: исправлено: setTimeZone не принимает строку (исправлено Paul)

Ответ 3

Java 8 Native

java.time упрощает работу с Java 8. И потокобезопасен.

ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )

Результат: 2015-04-14T11:07:36.639Z

Вы можете испытать желание использовать более легкие Temporal, такие как Instant или LocalDateTime, но им не хватает поддержки форматера или данных часового пояса. Только ZonedDateTime работает из коробки.

Настраивая или связывая параметры/операции ZonedDateTime и DateTimeFormatter, вы можете в определенной степени легко контролировать часовой пояс и точность. :

ZonedDateTime.now( ZoneId.of( "Europe/Paris" ) )
             .truncatedTo( ChronoUnit.MINUTES )
             .format( DateTimeFormatter.ISO_DATE_TIME )

Результат: 2015-04-14T11:07:00+01:00[Europe/Paris]

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

.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // 2015-04-14T11:07:00
.format( DateTimeFormatter.ISO_LOCAL_DATE ) // 2015-04-14
.format( DateTimeFormatter.ISO_LOCAL_TIME ) // 11:07:00
.format( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" ) ) // 2015-04-14 11:07

Для Java 6 & 7, вы можете рассмотреть обратные порты java.time, такие как ThreeTen-Backport, который также имеет порт Android. Оба легче, чем Йода, и учился на опыте Джоды experience - особенно. учитывая, что java.time разработан автором Joda.

Ответ 4

Java 8:

thisMoment = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
                              .withZone(ZoneOffset.UTC)
                              .format(Instant.now());

Предварительная Java 8:

thisMoment = String.format("%tFT%<tRZ",
                           Calendar.getInstance(TimeZone.getTimeZone("Z")));

От документы:

'R'   Время, отформатированное для 24-часовых часов как "% tH:% tM"
'F'   Дата завершения ISO 8601, отформатированная как" % tY-% tm-% td".

Ответ 5

Начиная с Java 8 вы можете просто:

Instant.now().toString();

Из java.time.Instant документов:

Теперь

public static Instant now()

Получает текущий момент от системных часов.

Это запросит системные часы UTC, чтобы получить текущий момент.

  ToString

public String toString()

Строковое представление этого момента с использованием представления ISO-8601.

Используемый формат такой же, как DateTimeFormatter.ISO_INSTANT.

Ответ 6

используйте JodaTime

Система календаря ISO 8601 является реализацией по умолчанию в Joda-Time

Здесь это документ для JodaTime Formatter

Изменить:

Если вы не хотите добавлять или не видите значения добавления выше библиотеки, вы можете просто использовать встроенный класс SimpleDateFormat для форматирования даты в требуемый формат ISO

как предложено @Joachim Sauer

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
String nowAsString = df.format(new Date());

Ответ 7

DateFormatUtils от Apache commons-lang3 имеют полезные константы, например: DateFormatUtils.ISO_DATETIME_FORMAT

Ответ 8

Если вы не хотите включать Jodatime (так же хорошо, как есть)

javax.xml.bind.DatatypeConverter.printDateTime(
    Calendar.getInstance(TimeZone.getTimeZone("UTC"))
);

который возвращает строку:

2012-07-10T16:02:48.440Z

который немного отличается от исходного запроса, но по-прежнему является ISO-8601.

Ответ 9

ISO 8601 может содержать секунды см. http://en.wikipedia.org/wiki/ISO_8601#Times

поэтому код должен быть

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

Ответ 10

Joda времени

Обновление: Проект Joda-Time теперь находится в режиме обслуживания, и команда рекомендует перейти на классы java.time. Для Java 6 & 7, см. проект ThreeTen-Backport, дополнительно адаптированный для Android в проекте ThreeTenABP.

Использование библиотеки Joda-Time...

String output = new DateTime( DateTimeZone.UTC ).toString() ;

Это потокобезопасно. Joda-Time создает новые неизменяемые объекты, а не изменяет существующие объекты.

Если вы действительно хотели запросить формат без секунд, с разрешением в минуты, используйте один из множества других встроенных форматеров в Joda-Time.

DateTime now = new DateTime( DateTimeZone.UTC ) ;
String output = ISODateTimeFormat.dateHourMinute.print( now ) ;

java.time

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

Смотрите мой другой ответ для современного решения.


О java.time

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

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

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

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версией. Нет необходимости в строках, нет необходимости в классах java.sql.*.

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

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

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

Ответ 11

Для Java версии 7

Вы можете ознакомиться с документацией Oracle: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

X - используется для часового пояса ISO 8601

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

System.out.println(nowAsISO);

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
//nowAsISO = "2013-05-31T00:00:00Z";
Date finalResult = df1.parse(nowAsISO);

System.out.println(finalResult);

Ответ 12

Вы можете использовать Java SimpleDateFormat со следующим шаблоном yyyy-MM-dd'T'HH:mm:ssXXX для ISO 8601.

Пример кода: (перечислены все доступные часовые пояса)

for (String timeZone : TimeZone.getAvailableIDs())
{
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
    dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
    String formatted = dateFormat.format(new Date());
    System.out.print(formatted);

    if (formatted.endsWith("Z"))
    {
        // These time zone have offset of '0' from GMT.
        System.out.print("\t(" + timeZone + ")");
    }

    System.out.println();
}

Вы можете использовать:

TimeZone.getDefault()

для часового пояса vm по умолчанию. Подробнее здесь

Вы можете заметить время даты для нескольких часовых поясов, которые заканчиваются на 'Z'. Эти часовые пояса имеют смещение '0' от GMT.

Более подробную информацию можно найти здесь.

Ответ 13

Я считаю, что самый простой способ - сначала перейти к мгновенному, а затем добавить строку как:

String d = new Date().toInstant().toString();

Это приведет к:

2017-09-08T12:56:45.331Z

Ответ 14

ТЛ; др

Некоторые из других ответов правильны в рекомендациях классов java.time, но при этом используют ненужные длины для ваших конкретных потребностей.

Instant.now()                               // Capture the current moment in UTC with a resolution as fines nanoseconds but usually in microseconds or milliseconds.
       .truncatedTo( ChronoUnit.MINUTES )   // Lop off any seconds or fractional second, to get a value in whole minutes.
       .toString()                          // Generate a String in standard ISO 8601 format where a 'T' separates the year-month-day from the hour-minute-second, and the 'Z' on the end for 'Zulu' means UTC.

2018-01-23T12:34Z

Instant::toString

Класс jav.time.Instant представляет момент в UTC, всегда в UTC.

Instant instant = Instant.now() ;

instant.toString(): 2018-01-23T12:34:56.123456Z

Z в конце строки вашего примера 2010-10-12T08:50Z произносится как "зулу" и означает UTC.

Ваш желаемый формат соответствует стандарту ISO 8601. Классы java.time по умолчанию используют эти стандартные форматы при разборе/генерации строк. Поэтому нет необходимости указывать шаблон форматирования. Просто позвоните Instant::toString, как показано выше.

Если вы хотите целые минуты без секунды или доли секунды, то обрежьте. Укажите единицу времени с помощью класса ChronoUnit.

Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES ) ;
String output = instant.toString();  // Generate a 'String' object in standard ISO 8601 format.

О java.time

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

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

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

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версией. Нет необходимости в строках, нет необходимости в классах java.sql.*.

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

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

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

Ответ 15

Здесь весь класс оптимизирован так, что вызов "now()" не делает ничего более того, что он должен делать.

public class Iso8601Util
{
    private static TimeZone tz = TimeZone.getTimeZone("UTC");
    private static DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");

    static
    {
        df.setTimeZone(tz);
    }

    public static String now()
    {
        return df.format(new Date());
    }
}

Ответ 16

private static String getCurrentDateIso()
{
    // Returns the current date with the same format as Javascript new Date().toJSON(), ISO 8601
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    return dateFormat.format(new Date());
}

Ответ 17

Тем не менее, joda-time поддерживает только расширенный формат: "2015-12-09T00: 22: 42.930Z" не основное: "20151209T002242.930Z" ... нам может быть лучше тестировать список форматов с помощью java SimpleDateFormat.

Ответ 18

Я сделал это в Android, используя Calendar и SimpleDateFormat. Следующий метод возвращает календарь с часовым поясом "GMT" (это универсальный часовой пояс). Затем вы можете использовать класс Calendar для установки часового пояса между разными часовыми поясами, используя метод setTimeZone() класса Calendar.

private static final String GMT = "GMT";
private static final String DATE_FORMAT_ISO = "yyyyMMdd'T'HHmmss";

public static Calendar isoToCalendar(final String inputDate) {
    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(GMT));
    try {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_ISO, Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone(GMT));
        Date date = dateFormat.parse(inputDate);
        calendar.setTime(date);
    } catch (ParseException e) {
        Log.e("TAG",e.getMessage());
    }
    return calendar;
}

ПОМНИТЕ: Класс Date не знает о существовании TimeZone. По этой причине, если вы отлаживаете одну дату, вы всегда видите дату своего текущего часового пояса.

Ответ 19

Им следовало бы добавить какой-то простой способ перехода от даты к мгновенному, а также метод под названием toISO8601, который ищут многие люди. В дополнение к другим ответам, от java.util.Date до формата ISO 8601:

Instant.ofEpochMilli(date.getTime()).toString();

Это не очень заметно при использовании автозаполнения, но: java.time.Instant.toString():

Строковое представление этого момента с использованием ISO-8601

Ответ 20

DateTimeFormatter.ISO_DATE_TIME
        .withZone(ZoneOffset.UTC)
        .format(yourDateObject.toInstant())

Ответ 21

Если вы заботитесь о производительности, я создал библиотеку, которая превосходит стандартные средства синтаксического анализа и форматирования Java в манипулировании датами в формате ISO8601. Реализации DatetimeProcessor являются поточно-ориентированными и могут кэшироваться в параллельной карте или в статических полях.

<dependency>
  <groupId>com.axibase</groupId>
  <artifactId>date-processor</artifactId>
  <version>1.0.3</version>
</dependency>
import com.axibase.date.DatetimeProcessor;
import com.axibase.date.PatternResolver;
import org.junit.Before;
import org.junit.Test;

import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

public class DateFormatTest {
    private Clock clock;

    @Before
    public void prepare() {
        clock = Clock.fixed(Instant.ofEpochMilli(1571285405300L), ZoneId.of("Europe/Berlin"));
    }

    @Test
    public void testIsoMillis(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10:05.300Z"));
    }

    @Test
    public void testIsoMillisLocalZone(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), clock.getZone()), is("2019-10-17T06:10:05.300+02:00"));
    }

    @Test
    public void testIsoMinutes(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("yyyy-MM-ddTHH:mmXXX");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10Z"));
    }
}

Ответ 22

Попробуйте это,

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
        String date=sdf.format (new Date() );

Его формат ISO 8601