В чем проблема?
Полный список проблем включает в себя:
- Вы используете плохо разработанные и давно устаревшие классы даты и времени Java
Date
, TimeZone
и SimpleDateFormat
.
- Вы используете устаревшие методы
getMonth
, getDate
и getYear
класса Date
. Эти методы работают ненадежно во всех часовых поясах, что является основной причиной, по которой они устарели.
- Вы переводите часовой пояс вручную, используя сложение, вычитание и умножение. Математика даты и времени подвержена ошибкам, и вы всегда должны оставлять ее проверенным библиотечным методам.
- Количество миллисекунд, полученное с
Date.getTime
, относится к периоду 1970-01-01T00: 00: 00 UTC. Это уникальный момент времени, не зависящий от часового пояса, поэтому нет смысла добавлять и вычитать из подсчета миллисекунд для преобразования часового пояса.
- Я могу воспроизвести ваш результат, если для часового пояса JVM по умолчанию установлено значение Азия / Сеул, и предположим, что
HOUR
равно 0 (или некоторому значению в диапазоне от 0 до 111). Я предполагаю, что вы хотели, чтобы HOUR
обозначало количество миллисекунд в час, 3 600 000 (по крайней мере, обычно существуют исключения).
- Вы форматировали свою дату, объединяя результаты звонков на
Strirg.format
. Лучше оставить форматирование в специализированном форматере даты.
Исправление: java.time
ZoneId serverTimeZone = ZoneId.of("Asia/Seoul");
DateTimeFormatter serverFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
ZoneId clientTimeZone = ZoneId.systemDefault();
String checkedDate = "2019-06-24 16:15:31";
ZonedDateTime serverDateTime = LocalDateTime.parse(checkedDate, serverFormatter)
.atZone(serverTimeZone);
ZonedDateTime clientDateTime = serverDateTime.withZoneSameInstant(clientTimeZone);
System.out.println("clientDateTime: " + clientDateTime);
Извините, что я могу писать и запускать только код Java, я надеюсь, что вы переведете. С часовым поясом моего JVM, установленным в Азия / Сеул, я получаю:
clientDateTime: 2019-06-24T16: 15: 31 + 09: 00 [Азия / Сеул]
Время сервера и время клиента совпадают, как вы просили. Если вместо этого я сохраню свой часовой пояс, я получу:
clientDateTime: 2019-06-24T09: 15: 31 + 02: 00 [Европа / Копенгаген]
Итак, происходит конверсия.
Для форматирования даты:
DateTimeFormatter displayFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("ko-KR"));
String transformedLocalDate = clientDateTime.format(displayFormatter);
System.out.println("transformedLocalDate: " + transformedLocalDate);
transformedLocalDate: 2019. 6. 24.
Или, если вы настаиваете на month.date.year:
DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("MM.dd.u");
transformedLocalDate: 24.06.2019
Еще одна рекомендация будет заключаться в том, чтобы ваш сервер доставлял строку даты и времени в формате UTC в формате ISO 8601. Это будет похоже на 2019-06-24T07:15:31Z
на данный момент, используемый в примерах.
Вопрос: Могу ли я использовать java.time с minSdk API level 23 на Android?
Да, java.time прекрасно работает на старых и новых устройствах Android. Для этого требуется как минимум Java 6 .
- В Java 8 и более поздних версиях и на более новых устройствах Android (начиная с уровня API 26) встроен современный API.
- В Java 6 и 7 получите ThreeTen Backport, бэкпорт современных классов (ThreeTen для JSR 310; см. Ссылки внизу).
- На (более старых) Android используется версия Android ThreeTen Backport. Это называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из
org.threeten.bp
с подпакетами.
Ссылки