Reputation: 5743
I have the following PeriodFormatter:
PeriodFormatter periodFormatter = new PeriodFormatterBuilder().printZeroAlways().minimumPrintedDigits(2).appendHours().appendSeparator(":")
.appendMinutes().rejectSignedValues(false).maximumParsedDigits(2).toFormatter();
and if I parse e.g. -03:00 (three hours):
final Duration hoursDuration = periodFormatter.parsePeriod(hours)
but if I parse e.g. -00:43 (45 minutes) than I get a positiv duration because the right format would be -00:-43.
My question now would be it there is a possibility with periodFormatter.
Upvotes: 0
Views: 696
Reputation: 44071
First I make your code compilable:
PeriodFormatter periodFormatter =
new PeriodFormatterBuilder().printZeroAlways().minimumPrintedDigits(2)
.appendHours().appendSeparator(":")
.appendMinutes().rejectSignedValues(false).maximumParsedDigits(2).toFormatter();
Period p1 = periodFormatter.parsePeriod("-03:00"); // PT-3H
System.out.println(p1);
Period p2 = periodFormatter.parsePeriod("-00:43"); // PT43M
System.out.println(p2);
Explanation for the observed behaviour:
Joda-Time handles the signs of any period in a counter-intuitive way since the very beginning. Signs are never related to the whole period but only to the single distinct components of a period.
The opinions about this behaviour are in dissent. While the Joda-team seems to consider this as enhancement and useful feature other people like me find it terrible. For example, it is possible to construct a period as P1M-30D. Is such a period positive, negative or zero? We don't really know. And the result is that a period looses the property to be like the length of a directed vector on the timeline (what is characteristic for a duration).
As far as I know there is no chance to change this behaviour in Joda-Time. If you want to parse "-00:43" as -PT43M then consider following options:
a) Manual workaround:
String input = "-00:43";
boolean negative = input.charAt(0) == '-';
Period p3 = periodFormatter.parsePeriod(input.replace("-", ""));
if (negative) {
p3 = p3.negated();
}
System.out.println(p3); // PT-43M
b) Using my library Time4J:
This is rather a cannon for solving your concrete problem but otherwise it is worth a look because the possibilities to normalize, format or parse any duration are overwhelming. Time4J rejects mixed signs so the sign can only be in front of the whole duration.
Duration<ClockUnit> d = Duration.formatter(ClockUnit.class, "-hh:mm").parse(input);
System.out.println(d); // -PT43M
Upvotes: 1