javaandroidiso8601periodtrial

How to convert ISO 8601 period to a string readable by humans [Android Studio]?


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!


Solution

  • java.time and ThreeTenABP

    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.

    Question: Can I use java.time on Android?

    Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.

    Links