Date () не улавливает изменение часового пояса - PullRequest
0 голосов
/ 30 апреля 2018

Мое приложение получает ответ от моего сервера с датой и временем прошлых событий. Мой сервер, однако, находится в другом часовом поясе, и здесь все становится немного сложнее. Часовой пояс сервера - UTC +01:00, а мой - UTC +03:00. Когда я получаю ответы от сервера, они приходят с отметкой времени в UTC +01:00. Сначала я попытался получить дату в виде String, подставив ее в строку, установив ее часовой пояс, а затем вернув ее в надлежащем формате и часовом поясе. (Я вырезал последние 4 цифры милисека, потому что DateFormat был недействительным в противном случае.)

private String getFormattedDate(String date) {
    DateFormat serverDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    DateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    Calendar calendar = Calendar.getInstance();
    TimeZone timeZone = calendar.getTimeZone();
    serverDateFormat.setTimeZone(timeZone);
    String cutoutDate = date.substring(0,23);
    String cutoutZone = date.substring(27, date.length());
    String dateInProperFormat = cutoutDate + cutoutZone;
    Date finalDate = serverDateFormat.parse(dateInProperFormat);
    return finalDateFormat.format(finalDate);
}

Это прочитало и преобразовало все правильно:

Ответ сервера: 2018-04-30T07:26:55.1524511+01:00 -> Подстроковой ответ: 2018-04-30T07:26:55.152+01:00 -> Окончательный формат: 30-04-2018 09:26:55

Однако milisec не всегда было 7, поэтому, когда это произошло, я получил ошибку Unparsable date. Это заставило меня прочитать дату не как String, а как Date. Это сократить код только до 5 строк:

private String getFormattedDate(Date date) {
    SimpleDateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    Calendar calendar = Calendar.getInstance();
    TimeZone timeZone = calendar.getTimeZone();
    finalDateFormat.setTimeZone(timeZone);
    return finalDateFormat.format(date);
}

Но сейчас время всегда в UTC +01:00. Я пытался получить часовой пояс так:

TimeZone timeZone = TimeZone.getDefault();

Но это ничего не изменило. Что именно я делаю неправильно во втором подходе? Я готов поделиться своим кодом, если это необходимо.

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

java.time

private static DateTimeFormatter finalDateTimeFormatter
        = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss");
private static ZoneId zone = ZoneId.of("Europe/Istanbul");

private static String getFormattedDate(String dateTime) {
    return OffsetDateTime.parse(dateTime)
            .atZoneSameInstant(zone)
            .format(finalDateTimeFormatter);
}

Давайте попробуем это на примере ответа сервера на ваш вопрос:

    System.out.println(getFormattedDate("2018-04-30T07:26:55.1524511+01:00"));

Выводит желаемое:

30-04-2018 09: 26: 55

Примечания:

  • one-arg OffsetDateTime.parse принимает от 1 до 9 десятичных знаков в секундах, поэтому вам не нужно каким-либо образом манипулировать строкой перед синтаксическим анализом.
  • Не используйте смещение UTC, равное UTC +03:00, в качестве часового пояса. Используйте часовой пояс, такой как Африка / Найроби, Европа / Москва, Азия / Катар или что подходит. Это лучше документирует, почему вы делаете то, что вы делаете, и это на будущее, если смещение будет изменено. Что происходит чаще, чем вы думаете.

Вопрос: Могу ли я использовать java.time на Android?

Да, java.time прекрасно работает на старых и новых устройствах Android. Просто требуется хотя бы Java 6 .

  • В Java 8 и более поздних версиях и на более новых устройствах Android (от 26 уровня API, как мне сказали) современный API поставляется встроенным.
  • В Java 6 и 7 получить ThreeTen Backport, бэкпорт новых классов (ThreeTen для JSR 310; см. Ссылки внизу).
  • На (более старых) Android используется версия Android ThreeTen Backport. Это называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из org.threeten.bp с подпакетами.

Ссылки

0 голосов
/ 30 апреля 2018

попробуйте код ниже. Это обходное решение

   public String getFormattedDate(String date) {
    DateFormat serverDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    DateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    Calendar calendar = Calendar.getInstance();
    TimeZone timeZone = calendar.getTimeZone();
    serverDateFormat.setTimeZone(timeZone);
    String[] splitTime=date.split("\\+");
    String cutoutDate="";
    if (splitTime[0].length()>23)cutoutDate = date.substring(0,23);
    else cutoutDate=splitTime[0];
    String cutoutZone = "+"+splitTime[1];
    String dateInProperFormat = cutoutDate + cutoutZone;
    Date finalDate = null;
    try {
        finalDate = serverDateFormat.parse(dateInProperFormat);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return finalDateFormat.format(finalDate);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...