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

java

316484 просмотра

22 ответа

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

Пример:

String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
Автор: yegor256 Источник Размещён: 12.11.2019 09:17

Ответы (22)


276 плюса

Решение

Используйте 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()как показано выше, отформатирует текущее время.

Автор: Joachim Sauer Размещён: 12.10.2010 12:10

218 плюса

Для систем, где часовой пояс по умолчанию не 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Экземпляр может быть объявлена как глобальная константа , если это необходимо часто, но нужно учитывать , что этот класс не является потокобезопасным. Он должен быть синхронизирован, если к нему одновременно обращаются несколько потоков.

РЕДАКТИРОВАТЬ: Я бы предпочел Joda Time, если делать много разных манипуляций с временем / датой ...
РЕДАКТИРОВАТЬ2: исправлено: setTimeZoneне принимает строку (исправлено Полом)

Автор: Carlos Heuberger Размещён: 12.10.2010 01:04

155 плюса

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 . Оба легче, чем Йода, и извлекли уроки из опыта Йоды - особенно. учитывая, что java.time разработан автором Йоды.

Автор: Sheepy Размещён: 14.04.2015 11:26

124 плюса

Java 8:

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

Pre Java 8:

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

Из документов :

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

Автор: aioobe Размещён: 12.10.2010 12:17

72 плюса

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

Instant.now().toString();

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

в настоящее время

public static Instant now()

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

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

 


public String toString()

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

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

Автор: Владимир Зайцев Размещён: 19.10.2015 03:45

26 плюса

использовать 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());
Автор: Jigar Joshi Размещён: 12.10.2010 12:05

20 плюса

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

Автор: yegor256 Размещён: 11.01.2013 08:36

18 плюса

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

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

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

2012-07-10T16:02:48.440Z

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

Автор: Matthew Buckett Размещён: 10.07.2012 04:04

16 плюса

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

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

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Автор: okwap Размещён: 09.10.2013 03:12

10 плюса

Joda времени

Обновление: Joda время проект сейчас находится в режиме технического обслуживания , с командой советуя миграции в 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 (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP… .

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

Автор: Basil Bourque Размещён: 08.04.2014 04:48

7 плюса

Для 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);
Автор: d.danailov Размещён: 08.04.2014 02:22

5 плюса

Вы можете использовать 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's have offset of '0' from GMT.
        System.out.print("\t(" + timeZone + ")");
    }

    System.out.println();
}

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

TimeZone.getDefault ()

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

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

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

Автор: always_a_rookie_to_learn Размещён: 04.11.2015 10:04

5 плюса

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

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

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

2017-09-08T12:56:45.331Z

Автор: Tuncay Göncüoğlu Размещён: 08.09.2017 12:57

4 плюса

ТЛ; др

Некоторые из других Ответов верны в рекомендациях классов 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 (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP… .

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

Автор: Basil Bourque Размещён: 04.05.2018 11:36

2 плюса

Вот целый класс, оптимизированный таким образом, что вызов "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());
    }
}
Автор: gilbertpilz Размещён: 14.11.2012 03:39

2 плюса

private static String getCurrentDateIso()
{
    // Returns the current date with the same format as Javascript's 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());
}
Автор: cprcrack Размещён: 28.09.2017 07:26

1 плюс

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

Автор: joão tiago viegas Размещён: 08.12.2015 02:44

1 плюс

Я сделал это в 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. По этой причине, если вы отлаживаете одну дату, вы всегда видите дату вашего текущего часового пояса.

Автор: Gerardo Suarez Размещён: 23.06.2017 04:30

1 плюс

Если вы заботитесь о производительности, я создал библиотеку, которая превосходит стандартные средства синтаксического анализа и форматирования 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"));
    }
}

Автор: Anton Rybochkin Размещён: 17.10.2019 03:59

0 плюса

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

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

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

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

Автор: Christophe Roussy Размещён: 03.04.2018 12:38

0 плюса

DateTimeFormatter.ISO_DATE_TIME
        .withZone(ZoneOffset.UTC)
        .format(yourDateObject.toInstant())
Автор: apen Размещён: 27.04.2018 03:08

-2 плюса

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

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

Его для формата ISO 8601

Автор: Surej Размещён: 21.12.2011 01:11
Вопросы из категории :
32x32