Как получить текущий момент в формате 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?
Проект 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?
Проект 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