Избегайте устаревших классов даты и времени
Другие ответы могут быть правильными, но устарели. Утомительные старые классы даты и времени в Java теперь унаследованы, их заменили классы java.time.
Аналогичным образом, проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Использование java.time
Instant
два раза (в секундах с начала эпохи)
В java.time мы представляем моменты на временной шкале в UTC как Instant
. Я предполагаю, что ваша эпоха такая же, как и у java.time, первого момента 1970 года в UTC (1970-01-01T00:00:00Z
). Обратите внимание, что Instant
имеет разрешение наносекунд. Удобный фабричный метод создает Instant
из целых секунд, как задано в Вопросе.
Instant start = Instant.ofEpochSecond( … );
Instant stop = Instant.ofEpochSecond( … );
Здесь мы используем текущий момент и несколько минут спустя.
Instant start = Instant.now() ;
Instant stop = start.plusSeconds( TimeUnit.MINUTES.toSeconds( 7L ) ) ; // Seven minutes as a number of seconds.
Duration
В java.time промежуток времени, не привязанный к временной шкале, представлен двумя способами. Для лет-месяцев-дней у нас есть Period
. Для часов-минут-секунд у нас есть Duration
.
Duration duration = Duration.between( start , stop );
Half-Open
Истекшее время рассчитывается с использованием подхода Half-Open. В этом подходе начало включительно , а окончание исключительно . Этот подход обычно используется в работе с датой и временем. Я считаю, что последовательное использование этого подхода в вашей кодовой базе поможет устранить ошибки и недоразумения из-за неоднозначностей и облегчит когнитивную нагрузку вашего программирования.
ISO 8601
Стандарт ISO 8601 определяет множество практических форматов для представления значений даты и времени в виде текста. Эти форматы разработаны для того, чтобы избежать двусмысленности, их легко анализировать на машине и интуитивно понятно для людей разных культур.
Классы java.time по умолчанию используют эти форматы при разборе и генерации строк.
Для промежутка времени, не привязанного к временной шкале, стандарт определяет формат из PnYnMnDTnHnMnS
, где P
обозначает начало, а T
отделяет любые годы-месяцы-дни от любых часов. минуты-секунды. Таким образом, полтора часа - PT1H30M
.
В нашем примере кода используется семь минут:
String outputStandard = duration.toString();
PT7M
См. Приведенный выше пример код, работающий в прямом эфире на IdeOne.com .
Я предлагаю придерживаться этих форматов, когда это возможно, особенно при обмене или сериализации данных времени и даты, но также рассмотреть возможность использования в пользовательском интерфейсе, где это уместно, и ваши пользователи могут быть обучены их использованию.
Я рекомендую никогда , используя формат часов-часов (например, 01:30 для полуторачасовых часов), поскольку этот формат совершенно неоднозначен с временем суток.
Получение деталей для построения строки
Если вы должны указать промежуток времени, как показано в Вопросе, вам нужно будет составить текст самостоятельно.
- Для
Period
, позвоните getYears
, getMonths
и getDays
, чтобы получить каждую часть.
- Как ни странно, класс
Duration
не имел таких геттеров в Java 8 , но получил их в Java 9 и позже: toDaysPart
, toHoursPart
, toMinutesPart
, toSecondsPart
и toNanosPart
.
Пример кода, простой и базовый для начала работы.
int days = duration.toDaysPart() ;
int hours = duration.toHoursPart() ;
int minutes = duration.toMinutesPart() ;
int seconds = duration.toSecondsPart() ;
int nanos = duration.toNanosPart() ;
StringBuilder sb = new StringBuilder( 100 );
if( days != 0 ) {
sb.append( days + " days" ) ;
};
if( hours != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( hours + " hours" ) ;
};
if( minutes != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( minutes + " minutes" ) ;
};
if( seconds != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( seconds + " seconds" ) ;
};
if( nanos != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( nanos + " nanos" ) ;
};
String output = sb.toString();
Или, возможно, вы могли бы написать более плавный код, используя DateTimeFormatterBuilder
способом, показанным Joda-Time в Ответе Балуса C .
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Проект Joda-Time , который сейчас находится в режиме обслуживания , рекомендует выполнить переход на java.time классы.
Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Где получить классы java.time?
- Java SE 8 и SE 9 и более поздние
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Android
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
, и fz more .