@Dementor
программист, архитектор, аналитик

Почему java.util.Date зависит от часового пояса?

Общая ситуация. В мобильном приложении собираются некоторые данные и периодически отправляются на сервер. Данные порождаются в виде объектов, которые записываются в базу. Процедура из минутного таймера запросом выбирает данные, восстанавливает изначальные объекты и, если данные существуют, то они отправляется на сервер. Данные могут порождаться как при интерактивной работе пользователя в Activity, так и в фоне в рамках работающего Service, который обрабатывает некоторые данные автоматически.

Технические подробности. Одно из полей объекта, который описывает событие, имеет тип java.util.Date - дата возникновения события. В базе оно хранится в виде поля типа INTEGER (хотя как мы знаем в SQLite это условность). При записи в базу я использую метод getTime() из даты. При восстановлении из базы я использую конструктор с параметром этого времени (микросекунд эпохи UNIX). Далее, при отправке на сервер данных в формате JSON, я получаю getTime() и делю результат на тысячу (что бы получить нормальное время UNIX).

Проблема в следующем: Иногда сообщения уходят с правильным временем, а иногда смещенные в будущее на значение часового пояса.

У меня при тестировании такого никогда не было, а у пользователей иногда возникает. Вчера мы смогли увидеть и проследить инцидент по горячим следам. Пользователь вызвал событие в 17:57, но увидел на сайте 20:57. После этого он сообщил мне (было 18 с мелочью и потому проблема получила 100% подтверждение). У пользователя на смартфоне было правильное время и правильный часовой пояс. В логах сервера (в сырых данных) я нашел запись за 17:57:30 со следующей информацией {"Date": 1427997440 ..._другие свойства_...}, что как не сложно убедится соответствует 02 Apr 2015 17:57:20 GMT. Таким образом установлено, что неправильное время пришло именно с мобильного приложения, а не возникло в результате сбоя обработки на сервере. К сожалению, после успешного соединения с сервером записи по переданным событиям удаляются из базы, а потому сейчас уже нельзя уточнить на котором этапе произошла проблема - до или после сохранения в БД.

Два варианта:
или в 17:57:20 конструкция (new Date()).getTime() == 1427997440000 (вместо 1427986640000)
или (new Date(1427986640000)).getTime() == 1427997440000

Какие есть идеи у уважаемых экспертов Android и опытных программистов Java?

P.S. Возможно это будет важно. Есть мысли, что тут проблема с отложенной оптимизацией виртуальной машины. Так как в этом же проекте я сталкивался с другими необъяснимыми вещами. К примеру, есть работающий код (упрощен):

int intCount = 0;
Cursor cursor = db.rawQuery(SELECT count(*) as count FROM table, null);
			if (cursor.getCount() > 0) {
cursor.moveToFirst();
...............
intCount = cursor.getInt(0));
...............
			}
cursor.close();
...............
object.field = intCount;

Так вот этот код часто запускается и вопросов к нему обычно нет. И вот владельцы одного из устройств стали жаловаться на падение программы. Смотрю сообщение об ошибках на Google Play - а там в последней строке этого примера (присваивание свойству объекта интовской локальной переменной) вызывается ошибка, что нельзя обращаться к данным закрытого курсора. Дописал всевдооперации с переменной до закрытия курсора и ошибка перестала возникать.
  • Вопрос задан
  • 1264 просмотра
Пригласить эксперта
Ответы на вопрос 2
@constv
у пользователя может быть установлен пояс не соответствующий текущему времени соответствующего этому поясу.
например, согласно пояса должно быть 15:00, а на устройстве пользователем вручную выставлено 16:00. а Date возвращает время согласно установленного пояса.
Ответ написан
aratj
@aratj
программер.
потому как , лучше время гонять в UTC что бы вообще все равно было что за время на девайсе.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы