Это проблема часового пояса. Точнее говоря, проблема неправильного использования SimpleDateFormat
для чего-то, для чего оно не предназначалось. Вот способ, которым вы можете воспроизвести:
TimeZone.setDefault(TimeZone.getTimeZone("America/St_Johns"));
SimpleDateFormat timeFormatter = new SimpleDateFormat("mm:ss", Locale.getDefault());
System.out.println(timeFormatter.format(new Date(5*60*1000)));
Вывод этого фрагмента:
35: 00
Пояснение:
new Date(5*60*1000)
дает дату-время через 5 минут после эпохи, то есть 00:05:00 UTC 1 января 1970 года. В это время, как и в любое другое время, разные зоны мира имеют разное время. Однако большинство часовых поясов имеют смещение от UTC на целое количество часов. Таким образом, время будет через 5 минут после часа, и ваш форматер напечатает его как 05:00. Вот почему вы не заметили проблему раньше. Например, в Берлине будет 01:05:00, а в Нью-Йорке будет 19:05:00 накануне вечером. Однако есть также часовые пояса, которые имеют смещения от UTC, которые не являются целым числом часов. Например, Азия / Калькутта в +05: 30 и Азия / Катманду в +05: 45. В таком часовом поясе время не будет на 5 минут позже часа, и вы получите неожиданный результат, подобный тому, который вы видели.
Предлагаемые решения включают в себя:
- Используйте
TimeUnit
для преобразования секунд в минуты и секунды и String.format
для их форматирования в две цифры.
- Если вам нужно хорошее решение, и вы в порядке с внешней зависимостью от старой библиотеки в режиме обслуживания, посмотрите на
PeriodFormatter
Joda-Time.
Вот пример использования TimeUnit
для расчета частей для форматирования, как это предлагается в первом пункте:
long totalSeconds = TimeUnit.MINUTES.toSeconds(5); // 300
long minutes = TimeUnit.SECONDS.toMinutes(totalSeconds);
long secondsPart = totalSeconds - TimeUnit.MINUTES.toSeconds(minutes);
String formattedDuration = String.format("%02d:%02d", minutes, secondsPart);
System.out.println("Formatted duration: " + formattedDuration);
Выход:
Форматированная продолжительность: 05: 00
Гадкий хак, который я бы не предложил, - это установить часовой пояс вашего форматера на UTC.
В этом вопросе гораздо больше вдохновения, с которым я уже связался в комментарии. На момент написания у него было 20 ответов. Я повторяю ссылку внизу.
И, кстати, даже для форматирования и анализа дат и времени вы можете рассмотреть , не используя SimpleDateFormat
. Это общеизвестно хлопотно и давно устарело. Вместо этого добавьте ThreeTenABP в свой проект Android, чтобы использовать java.time
, современный Java-интерфейс даты и времени. Намного приятнее работать.
Ссылки