java.time и правильный объект datetime, а не строка
Внутренне в вашей программе не представляйте момент времени в виде строки. Используйте правильный объект даты и времени. Разобрать строку, чтобы получить одну:
String str = "Mon, 18 Mar 2019 03:43:55 GMT";
// Parse for internal use
Instant when = DateTimeFormatter.RFC_1123_DATE_TIME.parse(str, Instant::from);
System.out.println(when);
2019-03-18T03: 43: 55Z
Строка, которую вы получили от API, представлена в стандартном формате RFC 1123 / RFC 822 (который включает в себя секунды, и они правильны, поскольку не допускают нарушения стандарта (хотя формат ISO 8601 мог бы быть даже более подходящим) )). Парсер для формата RFC 1123 / RFC 822 встроен в java.time, что избавляет нас от необходимости конструировать его самостоятельно из строки шаблона формата.
Я предположил, что момент времени является важной информацией здесь, и выбросил информацию, которая была передана в GMT (то же самое произошло в вашем коде в вопросе). Если смещение стоит сохранить, нам нужен OffsetDateTime
вместо Instant
, и тот же встроенный форматер по-прежнему работает:
OffsetDateTime whenWithOffset
= OffsetDateTime.parse(str, DateTimeFormatter.RFC_1123_DATE_TIME);
System.out.println(whenWithOffset);
2019-03-18T03: 43: 55Z
Трейлинг Z
на выходе означает UTC, что на практически совпадает с GMT (теоретическая разница меньше секунды).
Я полагаю, что секунды, о которых вы спрашивали, не повредят вашей программе. Я предполагаю, что вы только хотите избежать представления их вашему пользователю. В случае, если я ошибаюсь, убрать секунды легко, когда вы знаете, как:
Instant when = DateTimeFormatter.RFC_1123_DATE_TIME.parse(str, Instant::from)
.truncatedTo(ChronoUnit.MINUTES);
2019-03-18T03: 43: 00Z
Теперь для секунд установлено значение 0. truncatedTo
можно использовать таким же образом с OffsetDateTime
.
Предоставление пользователю в часовом поясе и локали пользователя без секунд
Я полагаю, что ваш пользователь хотел бы видеть дату и время без секунд в своем часовом поясе и в формате, обычном для его или ее культуры. Например:
DateTimeFormatter formatter
= DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
.withLocale(Locale.forLanguageTag("en-IN"));
ZonedDateTime whenInUsersTimeZone = when.atZone(ZoneId.of("Asia/Kolkata"));
String formatted = whenInUsersTimeZone.format(formatter);
System.out.println(formatted);
18/03/19, 9:13
Вы заметили:
- Время было преобразовано с 03:43 (GMT) в 09:13 (стандартное время Индии).
- Даже если время в вашей программе содержит секунды, они не отображаются.
Если вы хотите использовать язык форматирования JVM по умолчанию, используйте .withLocale(Locale.getDefault(Locale.Category.FORMAT))
(опускание этой части также полностью работает, но я предпочитаю явно указать, что мы полагаемся на значение по умолчанию). Если вы хотите использовать часовой пояс по умолчанию, используйте when.atZone(ZoneId.systemDefault())
.
Избегайте даты и SimpleDateFormat
Используемые вами классы даты и времени Date
и SimpleDateFormat
плохо разработаны и давно устарели. Вместо этого я использую java.time, современный Java-интерфейс даты и времени. Мне так приятнее работать.
Ссылка
Обучающее руководство по Oracle: Дата и время , объясняющее, как использовать java.time.