Reputation: 105
I am fetching a list of times from server and want to add to show the total time taken. But unable to find how to do. Because the time is in like a normal sentence.
15 min 24 s
1 min 56 s
18 min 3 s
2 h 48 min 46 s
How to add these data?
Upvotes: 0
Views: 69
Reputation: 339362
Use java.time.Duration
class with standard ISO 8601 input strings.
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
)
Educate the publisher of that data about the ISO 8601 standard that defines many formats for communicating date-time values as text.
The standard format for a span of time unattached to the timeline is PnYnMnDTnHnMnS
where the P
marks the beginning (think of that as "p" for "period") and the T
separates any years-months-days from any hours-minutes-seconds.
Your example inputs could be converted to ISO 8601 format.
Replace min
with M
. Replace h
with H
. And replace s
with S
.
Also, delete any SPACE characters. Prepend with PT
.
String input = "2 h 48 min 46 s" ;
String inputIso8601 =
"PT" +
input
.replace( "h" , "H" )
.replace( "min" , "M" )
.replace( "s" , "S" )
.replace( " " , "" )
;
Duration
The modern java.time classes in Java include Duration
. That class represents a span of time unattached to the timeline on a scale of hours-minutes-seconds.
That class knows how to parse and generate strings in standard ISO 8601 format.
Duration d = Duration.parse( inputIso8601 ) ;
That class also knows how to do math, adding and subtracting durations.
Duration dTotal = d1.plus( d2 ) ;
Let's make a method of that conversion code.
public String convertInputToIso8601 ( String input )
{
String inputIso8601 =
"PT" +
input
.replace( "h" , "H" )
.replace( "min" , "M" )
.replace( "s" , "S" )
.replace( " " , "" );
return inputIso8601;
}
Let's use your example inputs.
List < String > inputs = List.of(
"15 min 24 s" ,
"1 min 56 s" ,
"18 min 3 s" ,
"2 h 48 min 46 s"
);
Test converting the format of those inputs.
List < String > inputsIso8601 =
inputs
.stream()
.map( this :: convertInputToIso8601 )
.collect( Collectors.toList() )
;
Dump to console.
System.out.println(
inputsIso8601
);
[PT15M24S, PT1M56S, PT18M3S, PT2H48M46S]
That looks good. Now parse as Duration
objects.
List < Duration > durations =
inputsIso8601
.stream()
.map( Duration :: parse )
.collect( Collectors.toList() )
;
Dump to console.
System.out.println( durations );
[PT15M24S, PT1M56S, PT18M3S, PT2H48M46S]
That also looks good. Now do the math. The java.time classes use immutable objects. This means our math operations result in a new fresh object, rather than altering (mutating) the original.
Using conventional syntax to sum the durations.
Duration total = Duration.ZERO;
for ( Duration duration : durations )
{
total = total.plus( duration );
}
Using streams to sum the durations.
Duration total =
durations
.stream()
.reduce(
Duration.ZERO ,
Duration::plus
)
;
Dump to console.
System.out.println( "total = " + total );
total = PT3H24M9S
That worked. Your inputs totaled almost three and a half hours.
Here is that code again, all together.
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 );
I imagine we could combine those three streaming statements into a single one. But reading and debugging would likel’y be more difficult.
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
Upvotes: 3