Часовые пояса.
Длинное значение 5000
означает 5 секунд после эпохи. Для большинства часовых поясов через 5 секунд после эпохи это не 5 секунд после полуночи по местному времени.
Обновление Java 8 :
java.time.LocalTime
будет обрабатывать идею настенных часов «время суток», без необходимости беспокоиться о часовых поясах и днях, подразумеваемых в java.util.Date
. Если вы можете использовать Java 8, и ваша продолжительность будет всегда меньше суток, тогда правильная версия вашего примера может быть такой простой, как:
int millis = 5000;
int seconds = millis / 1000; // Maybe no need to divide if the input is in seconds
LocalTime timeOfDay = LocalTime.ofSecondOfDay(seconds);
String time = timeOfDay.toString();
(Строго говоря, java.time.Duration
- лучшая модель того, что вы хотите, в том смысле, что она представляет собой определенное количество секунд, а не время суток. Но это боль форматировать в чч: мм: сс, так что если вы всегда имеете дело со значениями меньше 24 часов, TimeOfDay предоставляет вам это форматирование бесплатно и в противном случае эквивалентно.)
Если вы застряли с Java 7 или ниже, то явное указание часового пояса GMT
в вашем примере кода должно дать ожидаемый результат.
Вот сеанс Scala REPL, демонстрирующий проблему, и решение Java 7 на моей машине:
scala> val millis = 5000
millis: Int = 5000
scala> val df = new java.text.SimpleDateFormat("HH:mm:ss")
df: java.text.SimpleDateFormat = java.text.SimpleDateFormat@8140d380
scala> df.format(millis)
res0: java.lang.String = 01:00:05
scala> df.getTimeZone.getID
res1: java.lang.String = GB
scala> df.getTimeZone.getOffset(millis)
res2: Int = 3600000
scala> df.setTimeZone(java.util.TimeZone.getTimeZone("GMT"))
scala> df.format(millis)
res3: java.lang.String = 00:00:05
Итак, вы можете видеть, что мой часовой пояс по умолчанию - GB
, который имеет смещение на 1 час от GMT во время, обозначенное 5000L
. Установка часового пояса в GMT дает ожидаемый результат 00:00:05
.