java - Joda Time sum various times -
i'm using joda time 2.7 , need add several times in localtime format , ignoring timezone , todatetimetoday ;
example:
input (string ... times)
01:10 , 01:10 , 01:10 ,
or
01:10 , 01:10 , 01:10 , 01:10 , 01:10 , 01:10
expected output in ( millis )
03:30
or expected output in ( millis )
07:00
my ideia
import org.joda.time.datetimezone; import org.joda.time.duration; import org.joda.time.format.datetimeformat; import org.joda.time.format.datetimeformatter; static long sumaccumulatedtimes( long... listtimes ){ duration duration = duration.zero; datetimezone zone = datetimezone.getdefault(); datetimeformatter fmt = datetimeformat.forpattern("hh:mm"); (int = 0; < listtimes.length; i++) { duration = duration.plus( listtimes[i] ); // in iteration three, ocurred problems! } long convertzone = zone.convertutctolocal( duration.getmillis() ); // adjust timezone system.out.println("output: " + fmt.print( convertzone ) ); return 0; // ignore ! } // call method datetimeformatter fmt = datetimeformat.forpattern("hh:mm"); sumaccumulatedtimes( fmt.parsemillis("01:10"), fmt.parsemillis("01:10")//, here ok (02:20 ouput), next inconsitent values // fmt.parsemillis("01:10") // add 3 parameters, ocurred problems );
edit: update
solved by @meno hochschild
string[] input = { "12:00", "12:10" }; periodformatter parser = new periodformatterbuilder() .appendhours().appendliteral(":") .appendminutes().toformatter(); period period = period.zero; (string s : input) { period = period.plus(parser.parseperiod(s)); } periodformatter printer = new periodformatterbuilder() .printzeroalways().minimumprinteddigits(2) //.appenddays().appendliteral(":") // remove original code .appendhours().appendliteral(":") .appendminutes().toformatter(); //system.out.println("duration=" + // remove original code //printer.print(period.normalizedstandard())); // output: duration=01:00:10 system.out.println("duration=" printer.print(period.normalizedstandard( periodtype.time() ))); // output: duration= 24:10
other soluction, @dexter :)
private static string sumaccumulatedtimes( string... times ){ datetimeformatter fmt = datetimeformat.forpattern("hh:mm"); datetimezone zone = datetimezone.getdefault(); periodformatter pformat = new periodformatterbuilder() .minimumprinteddigits(2) .printzeroalways() .appendhours() .appendliteral(":") .appendminutes() .toformatter(); long sum = 0; ( string time : times ) { long parselong = fmt.parsemillis( time ); sum += zone.convertutctolocal( parselong ); } period period = new period( sum ); return period.tostring(pformat); }
times sum 2 solutions work , ignoring time zone without limitation 24 hours
thank you.
don't use datetimeformatter
parse durations. formatter designed formatting , parsing points in time , cannot process time overflow , tries mangle calculated durations with timezone issues (the root cause of problem). in timezone "europe/berlin", expression fmt.parsemillis("01:10")
yields 10 minutes - not 1 hour , ten minutes.
use duration formatter instead. in joda-time, called periodformatter
:
string[] input = { "01:10", "01:10", "01:10", "01:10", "01:10", "01:10" }; periodformatter pf = new periodformatterbuilder() .minimumprinteddigits(2).printzeroalways() .appendhours().appendliteral(":").appendminutes().toformatter(); period period = period.zero; (string s : input) { period = period.plus(pf.parseperiod(s)); } system.out.println("duration=" + pf.print(period.normalizedstandard())); // output: duration=07:00
updated after comment of op (fix mishandling day overflow):
string[] input = { "12:00", "12:10" }; periodformatter parser = new periodformatterbuilder() .appendhours().appendliteral(":") .appendminutes().toformatter(); period period = period.zero; (string s : input) { period = period.plus(parser.parseperiod(s)); } periodformatter printer = new periodformatterbuilder() .printzeroalways().minimumprinteddigits(2) .appenddays().appendliteral(":") .appendhours().appendliteral(":") .appendminutes().toformatter(); system.out.println("duration=" + printer.print(period.normalizedstandard())); // output: duration=01:00:10
an alternative fix using expression period.normalizedstandard(periodtype.time())
in order use clock units only.