Any suggestions on how to convert the ISO 8601 duration format PnYnMnDTnHnMnS
(ex: P1W, P5D, P3D) to number of days?
I'm trying to set the text of a button in a way that the days of free trial are displayed to the user.
Google provides the billing information in the ISO 8601 duration format through the key "freeTrialPeriod", but I need it in numbers the user can actually read.
The current minimum API level of the app is 18, so the Duration and Period classes from Java 8 won't help, since they are meant for APIs equal or greater than 26.
I have set the following method as a workaround, but it doesn't look like the best solution:
private String getTrialPeriodMessage() {
String period = "";
try {
period = subsInfoObjects.get(SUBS_PRODUCT_ID).getString("freeTrialPeriod");
} catch (Exception e) {
e.printStackTrace();
}
switch (period) {
case "P1W":
period = "7";
break;
case "P2W":
period = "14";
break;
case "P3W":
period = "21";
break;
case "P4W":
period = "28";
break;
case "P7D":
period = "7";
break;
case "P6D":
period = "6";
break;
case "P5D":
period = "5";
break;
case "P4D":
period = "4";
break;
case "P3D":
period = "3";
break;
case "P2D":
period = "2";
break;
case "P1D":
period = "1";
}
return getString(R.string.continue_with_free_trial, period);
}
Any suggestions on how to improve it?
Thanks!
This exists. Consider not reinventing the wheel.
import org.threeten.bp.Period;
public class FormatPeriod {
public static void main(String[] args) {
String freeTrialString = "P3W";
Period freeTrial = Period.parse(freeTrialString);
String formattedPeriod = "" + freeTrial.getDays() + " days";
System.out.println(formattedPeriod);
}
}
This program outputs
21 days
You will want to add a check that the years and months are 0, or print them out too if they aren’t. Use the getYears
and getMonths
methods of the Period
class.
As you can see, weeks are automatically converted to days. The Period
class doesn’t represent weeks internally, only years, months and days. All of your example strings are supported. You can parse P1Y
(1 year), P1Y6M
(1 year 6 months), P1Y2M14D
(1 year 2 months 14 days), even P1Y5D
, P2M
, P1M15D
, P35D
and of course P3W
, etc.
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
java.time
rather than org.threeten.bp
.org.threeten.bp
with subpackages.java.time
. Section Period and Duration.java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).If you do want to re-invent the wheel here is a simple solution to parse ISO 8601 durations, it only supports year/week/day and not the time part but it can of course be added. Another limitation of this solution is that it expects the different types, if present, comes in the order Year->Week->Day
private static final String REGEX = "^P((\\d)*Y)?((\\d)*W)?((\\d)*D)?";
public static int parseDuration(String duration) {
int days = 0;
Pattern pattern = Pattern.compile(REGEX);
Matcher matcher = pattern.matcher(duration);
while (matcher.find()) {
if (matcher.group(1) != null ) {
days += 365 * Integer.valueOf(matcher.group(2));
}
if (matcher.group(3) != null ) {
days += 7 * Integer.valueOf(matcher.group(4));
}
if (matcher.group(5) != null ) {
days += Integer.valueOf(matcher.group(6));
}
}
return days;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With