Форум программистов, компьютерный форум, киберфорум
Наши страницы
Nikto
Войти
Регистрация
Восстановить пароль
Рейтинг: 5.00. Голосов: 1.

Баг TimeZone Android Java

Запись от Nikto размещена 06.06.2016 в 15:45
Обновил(-а) Nikto 08.06.2017 в 10:40

Разрабатывая одно приложение наткнулся на ошибку в переводе времени из одного часового пояса в другой.
Требовалось написать функцию перевода из текущей тайм зоны в тайм зону Москвы.

Получилась такая функция:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public Date getMskDateTime(Date d)
    {
        SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
        dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT+3"));
 
        SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
        TimeZone tz = TimeZone.getDefault();
        dateFormatLocal.setTimeZone(tz);
 
        try
        {
            return dateFormatLocal.parse(dateFormatGmt.format(d));
        } catch (ParseException e)
        {
            return new Date();
        }
    }
После были замечены баги, время переводится не всегда верно.
Проверяю у себя (моё локальное GMT+5) всё отлично работает, у другого же человека, у которого локальное GMT+6, время переводится неверно.
Перевожу у себя на GMT+6 и выявляю ту же ошибку. Перевожу на GMT+7 и опять всё верно переводит.
Т.е. при переводе на GMT+3: GMT+5 переводит на 2 часа, GMT+6 переводит опять на 2 часа (должен на 3), GMT+7 переводит на 4 часа как и должен.
Чудеса!
Ставлю у себя GMT+6. Вывожу то, что хранится в TimeZone.getDefault(). Вижу GMT+6.
Принудительно ставлю GMT+6 вместо default:
Java
1
TimeZone.getTimeZone("GMT+6");
И всё снова верно работает. МАГИЯ!
Думаю, что это баг андроида. Тестил на своём 4.4.

Решил прикрутить небольшой костыль, чтобы избавиться от проблемы.
В итоге решение выглядит так:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public Date getMskDateTime(Date d)
    {
        SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
        dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT+3"));
 
        SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
        TimeZone tz = TimeZone.getDefault();
        long hours = TimeUnit.MILLISECONDS.toHours(tz.getRawOffset());
        long minutes = TimeUnit.MILLISECONDS.toMinutes(tz.getRawOffset())
                - TimeUnit.HOURS.toMinutes(hours);
        minutes = Math.abs(minutes);
        tz = TimeZone.getTimeZone(String.format("GMT+%d:%02d", hours, minutes));
        dateFormatLocal.setTimeZone(tz);
 
        try
        {
            return dateFormatLocal.parse(dateFormatGmt.format(d));
        } catch (ParseException e)
        {
            return new Date();
        }
    }
Источник: https://catplusplus.ru/blog/bug_timezone_android_java
Размещено в Без категории
Просмотров 579 Комментарии 2
Всего комментариев 2
Комментарии
  1. Старый комментарий
    Аватар для HighPredator
    Это не может быть связано с тем, что мы в свое время отказались от перехода на летнее время? М.б. пакет не проапдейтили? Или я чего не так понимаю?
    Запись от HighPredator размещена 07.06.2016 в 12:27 HighPredator вне форума
  2. Старый комментарий
    Аватар для Nikto
    Цитата:
    Сообщение от HighPredator Просмотреть комментарий
    Это не может быть связано с тем, что мы в свое время отказались от перехода на летнее время? М.б. пакет не проапдейтили? Или я чего не так понимаю?
    Не знаю, но то, что если вручную прописать GMT+6, то всё работает, а если выбрать дефолтное, которое тоже GMT+6, то считает неверно и это как минимум неправильная работа java функций. Даже если дело в не проапдейтных пакетах, то юзеров с необновлёнными пакетами много и получается у них всех неправильно будет работать перевод в другую таймзону, а это уже пахнет багом.
    Запись от Nikto размещена 07.06.2016 в 13:42 Nikto вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru