tl; dr
Используйте класс java.time.Duration
со стандартными входными строками ISO 8601.
Duration total =
Duration
.parse(
"PT" +
"2 h 48 min 46 s"
.replace( "h" , "H" )
.replace( "min" , "M" )
.replace( "s" , "S" )
.replace( " " , "" )
)
.plus(
… another `Duration` object
)
ISO 8601
Обучите издателя этих данных о ISO 8601 стандарт, который определяет множество форматов для передачи значений даты и времени в виде текста.
Стандартный формат для промежутка времени , не привязанный к временной шкале, равен PnYnMnDTnHnMnS
, где P
отмечает начало (думайте об этом как «p» для «периода»), а T
отделяет любые годы-месяцы-дни от любых часов-минут-секунд.
Преобразование ваших входных данных
Ваши примеры входных данных могут быть преобразованы в формат ISO 8601.
Замените min
на M
. Заменить h
на H
. И заменить s
на S
.
Кроме того, удалите все символы пробела. Добавить с PT
.
String input = "2 h 48 min 46 s" ;
String inputIso8601 =
"PT" +
input
.replace( "h" , "H" )
.replace( "min" , "M" )
.replace( "s" , "S" )
.replace( " " , "" )
;
Duration
Современные java .time классы по Java включают Duration
. Этот класс представляет промежуток времени, не привязанный к временной шкале в масштабе часов-минут-секунд.
Этот класс знает, как анализировать и генерировать строки в стандартном формате ISO 8601.
Duration d = Duration.parse( inputIso8601 ) ;
Этот класс также знает, как выполнять математику, складывая и вычитая длительности.
Duration dTotal = d1.plus( d2 ) ;
Пример
Давайте создадим метод этого кода преобразования.
public String convertInputToIso8601 ( String input )
{
String inputIso8601 =
"PT" +
input
.replace( "h" , "H" )
.replace( "min" , "M" )
.replace( "s" , "S" )
.replace( " " , "" );
return inputIso8601;
}
Давайте используйте входные данные вашего примера.
List < String > inputs = List.of(
"15 min 24 s" ,
"1 min 56 s" ,
"18 min 3 s" ,
"2 h 48 min 46 s"
);
Проверка преобразования формата этих входов.
List < String > inputsIso8601 =
inputs
.stream()
.map( this :: convertInputToIso8601 )
.collect( Collectors.toList() )
;
Дамп в консоль.
System.out.println(
inputsIso8601
);
[PT15M24S, PT1M56S, PT18M3S, PT2H48M46S]
Это выглядит хорошо. Теперь выполните синтаксический анализ Duration
объектов.
List < Duration > durations =
inputsIso8601
.stream()
.map( Duration :: parse )
.collect( Collectors.toList() )
;
Дамп на консоль.
System.out.println( durations );
[PT15M24S, PT1M56S, PT18M3S, PT2H48M46S]
Это также выглядит хорошо. Теперь посчитай. Классы java .time используют неизменных объектов . Это означает, что наши математические операции приводят к созданию нового объекта fre sh, а не к изменению (изменению) оригинала.
Использование обычного синтаксиса для суммирования длительностей.
Duration total = Duration.ZERO;
for ( Duration duration : durations )
{
total = total.plus( duration );
}
Использование потоков для суммирования длительностей.
Duration total =
durations
.stream()
.reduce(
Duration.ZERO ,
Duration::plus
)
;
Дамп в консоль.
System.out.println( "total = " + total );
всего = PT3H24M9S
Это сработало. Ваши входные данные составили почти три с половиной часа.
Вот снова этот код, все вместе.
List < String > inputs = List.of(
"15 min 24 s" ,
"1 min 56 s" ,
"18 min 3 s" ,
"2 h 48 min 46 s"
);
List < String > inputsIso8601 = inputs.stream().map( this :: convertInputToIso8601 ).collect( Collectors.toList() );
System.out.println( inputsIso8601 );
List < Duration > durations = inputsIso8601.stream().map( Duration :: parse ).collect( Collectors.toList() );
System.out.println( durations );
Duration total = durations.stream().reduce( Duration.ZERO , Duration::plus ) ;
System.out.println( "total = " + total );
Я думаю, мы могли бы объединить эти три потоковых оператора в один. Но чтение и отладка были бы более сложными.
О java .time
java .time фреймворк встроен Java 8 и позже. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Чтобы узнать больше, см. Учебник Oracle . И поиск переполнения стека для многих примеров и объяснений. Спецификация: JSR 310 .
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java .time классы.
Вы можете обмениваться java .time объектами непосредственно с вашей базой данных. Используйте драйвер JDB C , совместимый с JDB C 4.2 или более поздней версией. Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где взять классы java .time?