I gets following strings from FE:
1m 5M 3D 30m 2h 1Y 3W
It corresponds to 1 minute, 5 months,3 days, 30 minutes, 2 hours, 1 year, 3 weeks.
Is there mean in java to parse it?
I want to manipulate(add/minus) with Instant(or LocalDatetTime). Is there way to do it in java?
Advertisement
Answer
Period & Duration
I consider the following solution simple and pretty general (not fully general).
public static TemporalAmount parse(String feString) {
if (Character.isUpperCase(feString.charAt(feString.length() - 1))) {
return Period.parse("P" + feString);
} else {
return Duration.parse("PT" + feString);
}
}
It seems that your date-based units (year, month, week, day) are denoted with uppercase abbreviations (Y, M, W and D) while the time-based ones (hour and minute) are lowercase (h and m). So I test the case of the last character of the string to decide whether to parse into a Period or a Duration. I exploit the fact that both of Period.parse and Duration.parse accept the letters in either case.
You wanted to add or subtract the durations to and from Instant or LocalDateTime. This works in most cases. Let’s see:
String[] timeAmountStrings = { "1m", "5M", "3D", "30m", "2h", "1Y", "3W" };
LocalDateTime base = LocalDateTime.of(2019, Month.MARCH, 1, 0, 0);
for (String tas : timeAmountStrings) {
TemporalAmount amount = parse(tas);
System.out.println("String: " + tas + " parsed: " + amount + " added: " + base.plus(amount));
try {
System.out.println("Added to Instant: " + Instant.EPOCH.plus(amount));
} catch (DateTimeException dte) {
System.out.println("Adding to Instant didn’t work: " + tas + ' ' + dte);
}
System.out.println();
}
Output:
String: 1m parsed: PT1M added: 2019-03-01T00:01 Added to Instant: 1970-01-01T00:01:00Z String: 5M parsed: P5M added: 2019-08-01T00:00 Adding to Instant didn’t work: 5M java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Months String: 3D parsed: P3D added: 2019-03-04T00:00 Added to Instant: 1970-01-04T00:00:00Z String: 30m parsed: PT30M added: 2019-03-01T00:30 Added to Instant: 1970-01-01T00:30:00Z String: 2h parsed: PT2H added: 2019-03-01T02:00 Added to Instant: 1970-01-01T02:00:00Z String: 1Y parsed: P1Y added: 2020-03-01T00:00 Adding to Instant didn’t work: 1Y java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Years String: 3W parsed: P21D added: 2019-03-22T00:00 Added to Instant: 1970-01-22T00:00:00Z
We see that adding to LocalDateTime works in all cases. Adding to Instant works in most cases, only we cannot add a period of months or years to it.