Какой самый элегантный способ получить форматирование в формате ISO 8601 текущего момента, UTC? Это должно выглядеть так: 2010-10-12T08:50Z
.
Пример:
String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
Какой самый элегантный способ получить форматирование в формате ISO 8601 текущего момента, UTC? Это должно выглядеть так: 2010-10-12T08:50Z
.
Пример:
String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
Используйте 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()
, как показано выше, отформатируйте текущее время.
Для систем, где часовой пояс по умолчанию не является 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)
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.
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".
Начиная с Java 8 вы можете просто:
Instant.now().toString();
Из java.time.Instant
документов:
Теперь
public static Instant now()
Получает текущий момент от системных часов.
Это запросит системные часы UTC, чтобы получить текущий момент.
ToString
public String toString()
Строковое представление этого момента с использованием представления ISO-8601.
Используемый формат такой же, как
DateTimeFormatter.ISO_INSTANT
.
используйте 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());
DateFormatUtils от Apache commons-lang3
имеют полезные константы, например: DateFormatUtils.ISO_DATETIME_FORMAT
Если вы не хотите включать Jodatime (так же хорошо, как есть)
javax.xml.bind.DatatypeConverter.printDateTime(
Calendar.getInstance(TimeZone.getTimeZone("UTC"))
);
который возвращает строку:
2012-07-10T16:02:48.440Z
который немного отличается от исходного запроса, но по-прежнему является ISO-8601.
ISO 8601 может содержать секунды см. http://en.wikipedia.org/wiki/ISO_8601#Times
поэтому код должен быть
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Обновление: Проект 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 8 и более поздних версий Joda-Time продолжает работать. Но встроенный java.time каркас вытесняет Joda-Time. Поэтому перенесите свой код из Joda-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
и еще.
Для 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);
Вы можете использовать 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.
Более подробную информацию можно найти здесь.
Я считаю, что самый простой способ - сначала перейти к мгновенному, а затем добавить строку как:
String d = new Date().toInstant().toString();
Это приведет к:
2017-09-08T12:56:45.331Z
Некоторые из других ответов правильны в рекомендациях классов 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 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
и еще.
Здесь весь класс оптимизирован так, что вызов "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());
}
}
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());
}
Тем не менее, joda-time поддерживает только расширенный формат: "2015-12-09T00: 22: 42.930Z" не основное: "20151209T002242.930Z" ... нам может быть лучше тестировать список форматов с помощью java SimpleDateFormat.
Я сделал это в 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. По этой причине, если вы отлаживаете одну дату, вы всегда видите дату своего текущего часового пояса.
Им следовало бы добавить какой-то простой способ перехода от даты к мгновенному, а также метод под названием toISO8601
, который ищут многие люди.
В дополнение к другим ответам, от java.util.Date до формата ISO 8601:
Instant.ofEpochMilli(date.getTime()).toString();
Это не очень заметно при использовании автозаполнения, но:
java.time.Instant.toString()
:
Строковое представление этого момента с использованием ISO-8601
DateTimeFormatter.ISO_DATE_TIME
.withZone(ZoneOffset.UTC)
.format(yourDateObject.toInstant())
Если вы заботитесь о производительности, я создал библиотеку, которая превосходит стандартные средства синтаксического анализа и форматирования 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"));
}
}
Попробуйте это,
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
String date=sdf.format (new Date() );
Его формат ISO 8601