В Java> = 8 вы можете использовать новый java.time
API .
Вход содержит:
- a unix timestamp (
1325134800000
), то есть число миллисекунд, прошедших с начала эпохи Unix (1970-01-01T00:00Z
) - a Смещение UTC (
-0500
), что отличается от UTC (в данном случае на 5 часов позже UTC)
В новом java.time
API имеется лотов различных типов объектов даты / времени.В этом случае мы можем выбрать использование java.time.Instant
(которое представляет количество наносекунд после эпохи Unix) или java.time.OffsetDateTime
(которое представляет Instant
, преобразованное в дату / время с определенным смещением).
Для разбора String
я использую java.time.format.DateTimeFormatterBuilder
для создания java.time.format.DateTimeFormatter
.Я также использую java.time.temporal.ChronoField
, чтобы указать, какие поля я анализирую:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// epoch seconds
.appendValue(ChronoField.INSTANT_SECONDS)
// milliseconds
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
// offset
.appendPattern("xx")
// create formatter
.toFormatter();
Я также использую регулярное выражение для извлечения только релевантной части из ввода String
(хотя вы также можете использовать substring()
чтобы получить его):
String s = "/Date(1325134800000-0500)/";
// get just the "1325134800000-0500" part - you can also do s.substring(6, 24)
s = s.replaceAll(".*/Date\\(([\\d\\+\\-]+)\\)/.*", "$1");
Затем я могу разобрать нужный тип:
// parse to Instant
Instant instant = Instant.from(fmt.parse(s));
// parse to OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(s, fmt);
Instant
эквивалентно 2011-12-29T05:00:00Z
(Instant
простоточка на временной шкале, и вы можете думать, что это всегда в UTC).OffsetDateTime
имеет тот же момент, но преобразован в смещение -0500
, поэтому его значение равно 2011-12-29T00:00-05:00
.Но и Instant
, и OffsetDateTime
представляют один и тот же момент времени.
Чтобы преобразовать в java.util.Date
, используйте Instant
:
// convert to java.util.Date
Date date = Date.from(instant);
// if you have an OffsetDateTime, you can do this:
Date date = Date.from(odt.toInstant());
Это потому, чтоjava.util.Date
не имеет информации о часовом поясе / смещении , и он просто представляет количество миллисекунд с начала эпохи Unix (та же концепция Instant
), поэтому его можно легко преобразовать из Instant
.
Java 6 и 7
Для Java 6 и 7 вы можете использовать ThreeTen Backport , отличный backport для новых классов даты / времени в Java 8.А для Android вам также потребуется ThreeTenABP (подробнее о том, как его использовать здесь ).
Отличие от Java 8это имена пакетов (в Java 8 java.time
и в ThreeTen Backport (или ThreeTenABP Android) org.threeten.bp
), но классы и методы names одинаковы.Таким образом, создание форматера и код разбора на Instant
и OffsetDateTime
одинаковы.
Другое отличие состоит в том, что в Java <= 7 класс <code>java.util.Date не имеет метода from()
.Но вы можете использовать класс org.threeten.bp.DateTimeUtils
для преобразования:
// convert to java.util.Date
Date date = DateTimeUtils.toDate(instant);
// or from the OffsetDateTime
Date date = DateTimeUtils.toDate(odt.toInstant());