2017-02-23 2 views
0

меня есть служба отдыха, который принимает дату в виде строки и адаптер анализирует его java.util.Date:Java Дата сместилась часа после разбора

private static final String FORMAT_DATE = "dd.MM.yyyy"; 

/* 
    * Omitted. 
    */ 

SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE); 
sdf.setLenient(false); 

try { 
    setTime(sdf.parse(stringRealizationDate).getTime()); 
    invalidDate = false; 
} catch (ParseException parseException) { 
    invalidDate = true; 
    LOG.error("Instantiation failed"); 
} 

stringRealizationDate является: 23.02.2017 и после разбора он становится 22.02.2017 23:00. Как сделать это всегда 23.02.2017 00:00 без каких-либо аспектов часовых поясов? Он не может быть перемещен ни при каких обстоятельствах.

+0

Как вы обнаружили, что самое время «22.02.2017 23:00»? –

+0

setTime (sdf.parse (stringRealizationDate) .getTime()); после этого дата 22.02 – michealAtmi

+0

Я попытался 'Date date = sdf.parse (stringRealizationDate)', напечатал его как 'date.toString()', и он дает мне выход 'Thu Feb 23 00:00:00 IST 2017'. Проверьте функцию setTime. – SachinSarawgi

ответ

0

Вы не можете полагаться на разбор строки, не содержащей явных сведений о часовом поясе, без какого-либо определения часового пояса.

SimpleDateFormat внутренне использует Calendar для хранения результата анализа. Этот календарь будет создан с использованием языка системы и, следовательно, системного часового пояса. Ваш stringRealizationDate будет рассматриваться как переданный с контекстом системного часового пояса, который, как представляется, +01:00.

Теперь SimpleDateFormat.parse() возвращает Date. Date, однако, предназначено для хранения UTC значений, поэтому смещение часового пояса +01:00 приводит к выпадению одного часа во время преобразования в UTC.

Одно из решений, имеющих правильный часовой пояс (+01:00) установлен при использовании вашего Date поэтому расчет с UTC к +01:00 приведет правильное значение быть, например, напечатан на экране. Но это довольно сложно управлять в более крупных приложениях.

Еще одно решение будет использовать SimpleDateFormat.setTimeZone(), прежде чем звонить parse(), чтобы явно определить часовой пояс, который должен принимать ваш форматирующий элемент (если он явно не определен). Тем не менее, проблема с наличием Date, которая всегда несет UTC значения часового пояса вообще не решены.

Лучшим решением будет использование нового Time API, доступного с Java8. Там у вас есть классы, в которых явным образом хранятся неработающие часы, в вашем случае LocalDate.

Интересным методом будет LocalDate.parse(CharSequence text, DateTimeFormatter formatter), так как он позволяет передавать ваш ввод строки и определять ожидаемый формат даты. Но будьте бдительны, вы не можете преобразовать LocalDate в Unix timestamp без прохождения часового пояса (и делать предположения о временных частях), так как он не представляет собой точное время, а его фрагмент - дату.