Я использую Android, JUnit и SimpleDateFormat
.
Мне нравится делать некоторые преобразования между String
и Date
в формате rfc3339 с часовым поясом.
Например: 2017-12-31T23:59:59+02:00
, но не 2017-12-31T23:59:59+0200
.
Android SimpleDateFormat
использует шаблон Z
, но не использует шаблон X
(см. RFC3339_REGEX_1
ниже).
Но в моем тесте JUnit (jdk1.8) RFC3339_REGEX_1
дает мне не правильный формат (+02:00
), а +0200
. Тест JUnit хорошо работает с RFC3339_REGEX_2
.
Итак, как я могу сделать что-то чистое, которое хорошо работает как на устройстве Android, так и в тесте JUnit?
public static final String RFC3339_REGEX_1 = "yyyy-MM-dd'T'HH:mm:ssZ"; //android
public static final String RFC3339_REGEX_2 = "yyyy-MM-dd'T'HH:mm:ssXXX"; //java
1 ответ
Старые классы (Date
, Calendar
и SimpleDateFormat
) имеют множество проблем и проблемы с дизайном, и они заменяются новыми API. И если я не ошибаюсь, шаблон X
не работает во всех версиях (я знаю, что в JDK 6 не поддерживался, он был представлен только в JDK 7; не знаю, как это повлияет на разные версии Android).
В качестве альтернативы в Android вы можете использовать ThreeTen Backport. Чтобы он работал, вам также понадобится ThreeTenABP (см. Как его использовать здесь ).
Однако, если вам все еще нужно работать с java.util.Date
, этот API может упростить вам задачу. Если вам нужен такой формат, как 2017-12-31T23:59:59+02:00
, вы можете преобразовать java.util.Date
в org.threeten.bp.OffsetDateTime
(используя класс org.threeten.bp.DateTimeUtils
для преобразования значений и org.threeten.bp.ZoneOffset
для установки смещение до +02:00
):
// assuming that java.util.Date has value equivalent to 2017-12-31T23:59:59+02:00
Date date = ...
// convert to OffsetDateTime (use +02:00 offset)
OffsetDateTime odt = DateTimeUtils.toInstant(date).atOffset(ZoneOffset.of("+02:00"));
System.out.println(odt); // 2017-12-31T23:59:59+02:00
Результат будет:
2017-12-31T23: 59: 59 + 02: 00
Обратите внимание, что это результат odt.toString()
(который называется неявным по System.out.println
), и по умолчанию он соответствует желаемому формату. Но вы также можете применить определенный формат, используя org.threeten.bp.format.DateTimeFormatter
:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
System.out.println(fmt.format(odt));
Выход такой же. Единственное отличие состоит в том, что первая версия (с использованием toString()
) будет печатать доли секунды, если они не равны нулю, и будет опускать секунды, если они равны нулю, а вторая версия (с форматером) всегда будет печатать в желаемом формате (в данном случае выведите секунды, но не доли секунд), независимо от того, равны ли значения нулю или нет.
Я считаю, что в вашем случае вам понадобится форматер, поскольку вам, кажется, всегда нужен формат с секундами и без доли секунд.
Чтобы преобразовать OffsetDateTime
обратно в Date
, вы также можете использовать DateTimeUtils
:
// convert back to java.util.Date
date = DateTimeUtils.toDate(odt.toInstant());
Если вам не нужно работать с java.util.Date
, вы можете использовать OffsetDateTime
напрямую:
// create OffsetDateTime with value = 2017-12-31T23:59:59+02:00
OffsetDateTime odt = OffsetDateTime.of(2017, 12, 31, 23, 59, 59, 0, ZoneOffset.ofHours(2));
Также обратите внимание, что я использовал ZoneOffset.ofHours(2)
, что эквивалентно ZoneOffset.of("+02:00")
.
Вы также можете получить текущую дату, используя OffsetDateTime.now(ZoneOffset.ofHours(2))
.
ThreeTen Backport - это резервный порт для новых классов даты и времени Java 8, и он имеет много разных типов даты и времени (например, OffsetDateTime
выше), которые можно использовать в различных ситуациях. Ознакомьтесь с этим руководством для получения дополнительной информации о том, какой тип лучше всего подходит для вашего case - в руководстве рассматривается Java 8, но в ThreeTen Backport те же имена классов и методов, только пакет отличается: org.threeten.bp
вместо java.time
.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].
Temporal
илиTemporalAccessor
.Instant
Instant
класс - это разрешение.