Вы не инициализирован ваш SimpleDateFormat форматировщик с объектом Calendar, поэтому он использует по умолчанию один, чтобы сделать отображение. Я предполагаю, что этот календарь по умолчанию распознает DST. Это не проявляется, когда вы .parse() datetimes, потому что настройка DST отменяется при вычитании.
При преобразовании результата в формат HMS форматер снова применяет настройку DST. Поскольку на этом шаге нет вычитания, оно появляется в вашем результате.
Мне кажется, что всякий раз, когда у кого-то есть арифметический вопрос по дате, ответ рефлекса резинового штампа и коленного рефлекса «используется JodaTime». Мы все любим JodaTime; это хорошо продуманный API. Но использование его по-прежнему является внешней зависимостью, и если вы не используете ее, вы не должны ее использовать. На мой взгляд, для этой ситуации вам совсем не нужен JodaTime ... вам нужен только Java Calendar API для анализа ваших дат в Датах. И это все, в чем ты нуждаешься.
Как только у вас есть разница в миллисекундах, вам действительно следует избегать использования форматирования для преобразования результата обратно. Используя простую арифметику, будет намного более производительным:
private static final SimpleDateFormat DATE_FORMAT =
new SimpleDateFormat("d MMM yyyy HH:mm:ss.SSS");
private static final int DAYS = 0;
private static final int HOURS = 1;
private static final int MINUTES = 2;
private static final int SECONDS = 3;
private static final int MILLIS = 4;
private final int[] result = new int[MILLIS];
public String calculateDuration(String startDateStr, String endDateStr){
try {
Date startDate = DATE_FORMAT.parse(startDateStr);
Date endDate = DATE_FORMAT.parse(endDateStr);
} catch (Exception e) { /* exception processing */ }
long diff = endDate.getTime() - startDate.getTime();
double d;
for (int i = DAYS; i <= MILLIS; i++) {
switch(i) {
case DAYS:
d = ((double) diff)/(86400.0 * 1000.0);
break;
case HOURS:
d = d * 24.0; break;
case MINUTES: case SECONDS:
d = d * 60.0; break;
case MILLIS:
d = d * 1000.0; break;
}
result[i] = (int) Math.floor(d);
d = d - (double) result[i];
}
В заключении этого последнего for
цикла, массив result
содержит целые числа, которые соответствуют количеству дней, часы, минуты, секунды и Миллис происходит от вашей даты вычитание. Для получения этого результата не нужно создавать, выделять или вызывать объекты. Теперь вы можете легко использовать функцию String.format()
, чтобы поместить эти целые числа в строковый формат по вашему выбору.
Является ли это Java? Подумайте о том, чтобы дать ему языковой тег – doctorlove
Является ли ваш TZ UTC + 1? –
Я думаю, вы должны использовать [* JodaTime *] (http://joda-time.sourceforge.net/) для вычисления разницы во времени (продолжительности). Это упростит вашу жизнь. – LaurentG