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.