Я собираюсь основывать свой ответ на отредактированной части кода, поскольку BicycleDude уже указал, что не так с операциями по модулю.
long diffms = date2l - date1l; //difference in ms
long ts = diffms / 1000; //total difference in seconds
long mo = ts / 60 / 60 / 24 / 30; //(1)
long d = (ts - mo * 30 * 24 * 60 * 60) / (60 * 60 * 24); //follows on because of (1)
long h = (ts - d * 24 * 60 * 60) / (60 * 60); //follows on because of (1)
long m = (ts - h * 60 * 60) / 60; //follows on because of (1)
Хорошо, я думал, что будет несколько проблем, но я думаю ( думаю , я, вероятно, что-то упускаю ...), что основная ошибка исходит из вашего расчета месяцев, который я обозначил в коде по комментарию (1)
. Вы не можете рассчитать разницу в таких месяцах.
Почему? А что, если различий было больше одного месяца? Не нужно ли вместо этого делить на 31? Или если это был високосный год? Вы должны были бы разделить на 29, если бы это был февраль. Поскольку целочисленное деление не округляется или не учитывает десятичные дроби, вы можете получить неточности в своих расчетах разницы в месяцах. Вероятно, будет лучше, если вместо этого вы будете использовать разницу в часах для расчета разницы в днях, и оттуда вы сможете вычислить разницу в месяцах. ( Редактировать : я думаю, что вам также необходимо учитывать факторы, которые я упоминал выше, при расчете разницы в месяцах от разницы в днях, проверяя, каковы ваши "исходные" и "целевые" даты хотя я не был бы слишком уверен в том, чтобы написать это сам на этой стадии ...)
Поскольку у вас есть проблема с тем, как вы вычисляете разницу в месяцах, и вы используете ошибочное значение для вычисления разницы в днях, я думаю, что это приводит к ошибке, распространяющейся до некоторых других ваших значений (например, разница в часах).
EDIT
Ладно, я немного больше разбираюсь с кодом. Как я уже отмечал ранее, ваши расчеты по месяцам были опасны и влияли на ваши расчеты дней, что впоследствии могло привести к ошибкам.
С примером, приведенным вами в комментариях, ваш код имел несоответствие 3 дням в количестве дней. (Пример был с 19 января 2012 года по 3 мая 2012 года). Я запустил это против кода BicycleDude, и это было нормально.
Я опубликую код, и я только что добавил одну строку, чтобы узнать количество дней, исходя из того, сколько часов прошло.
long h = ts / 60 / 60; // hour part
long m = (ts - h * 60 * 60) / 60; // minute part
long s = (ts - h * 60 * 60 - m * 60); // second part
long d = h / 24;
Если вы хотите сделать так, чтобы вы могли читать, что «между * date_l и date1l 'есть w
дней, x
часов, y
минут и z
секунд", вы можете сделать что-то вроде этого:
long date2l = Timestamp.valueOf("2012-05-03 05:30:10").getTime();
long date1l = Timestamp.valueOf("2012-01-19 00:00:00").getTime();
long diffms = date2l - date1l; //difference in ms
long diff_seconds = diffms / 1000; //total difference in seconds
long diff_mins = diff_seconds / 60; //total difference in minutes
long diff_hours = diff_mins / 60; //total difference in hours
long diff_days = diff_hours / 24; //total difference in days
long x = (diff_seconds - diff_days * 60 * 60 * 24) / (60 * 60);
long y = ((diff_seconds - (diff_hours * 60 * 60))) / 60;
long z = ((diff_seconds - (diff_mins * 60)));
long w = diff_days;
System.out.println(w + " " + x + " " + y + " " + z);
И, похоже, работает.
Я не разобрался в части месяцев, потому что это гораздо более нетривиально, но да. Это вроде работает?