Почему расчет TimeUnit такой неправильный?
Другие ответы верны: вы выполняли обратное преобразование того, которое планировали.TimeUnit.MILLISECONDS.convert(difference, TimeUnit.DAYS);
конвертируется из дней в миллисекунды.
Но почему вы получили отрицательное число ??Это из-за переполнения int
.Обратное преобразование было выполнено правильно и дало 434 758 135 795 200 000. Это намного больше, чем 32-битный int
.Поэтому, когда вы приводите к int
, самые значимые биты обрезаются.Случайно, бит, который в конечном итоге стал знаковым битом int
, был 1, что означает отрицательный.Я обычно избегаю делать такой бросок без проверки дальности.Вы можете приобрести ту же привычку.Math.toIntExact()
очень полезен здесь.
Как исправить: java.time
Другие ответы по-прежнему в основном верны.Тем не менее, я хотел бы предоставить пару предложений.
Если вы считаете, что время, скажем, с 16:04 один день до 16:04 следующего дня составляет 1 день, то вам нужно использовать часовой поясчтобы получить правильный результат.Например:
ZoneId zone = ZoneId.of("Africa/Mogadishu");
ZonedDateTime birth = Instant.ofEpochMilli(ts).atZone(zone);
long ageInDays = ChronoUnit.DAYS.between(birth, ZonedDateTime.now(zone));
System.out.println(ageInDays);
В этом случае результат выполнения кода прямо сейчас также тот, который вы ожидали:
58
Если, с другой стороны, вы определяете 1 день как 24 часа, независимо от того, что показывают настенные часы, вот способ получить возраст с точностью до секунды.Вы всегда можете преобразовать в последующие дни.
Instant birth = Instant.ofEpochMilli(ts);
Duration age = Duration.between(birth, Instant.now());
System.out.println(age);
System.out.println(age.toDays());
Вывод:
PT1398H52M13.994841S
58
В первой из двух строк указано, что возраст составляет 1398 часов 52 минуты 13,994841 секунды.Вторая строка согласуется с предыдущим результатом.
Мысли о двух фрагментах также можно комбинировать и смешивать.В целом, я думаю, что java.time
дает некоторые возможности, которые было бы труднее получить с помощью TimeUnit
, и некоторый довольно четкий и понятный код, в котором вы не могли бы легко совершить ту же ошибку, что и в вопросе.
Ссылки: