Как преобразовать период ISO 8601 в строку, читаемую людьми [Android Studio]? - PullRequest
0 голосов
/ 14 января 2019

Любые предложения о том, как преобразовать формат ISO 8601 PnYnMnDTnHnMnS (например: P1W, P5D, P3D) в количество дней?

Я пытаюсь настроить текст кнопки таким образом, чтобы дни бесплатной пробной версии отображались для пользователя.

Google предоставляет информацию для выставления счетов в формате продолжительности ISO 8601 через ключ "freeTrialPeriod", но он мне нужен в цифрах, которые пользователь действительно может прочитать.

Текущий минимальный уровень API приложения - 18, поэтому классы Duration и Period из Java 8 не помогут, поскольку они предназначены для API, равных или превышающих 26.

Я выбрал следующий метод в качестве обходного пути, но он не выглядит лучшим решением:

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);
    }

Есть предложения по улучшению?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Если вы хотите заново изобрести колесо, это простое решение для анализа продолжительности ISO 8601, оно поддерживает только год / неделю / день, а не часть времени, но, конечно, может быть добавлено. Другое ограничение этого решения состоит в том, что он ожидает, что различные типы, если они есть, будут иметь следующий порядок: год-> неделя-> день

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;
}
0 голосов
/ 14 января 2019

java.time и ThreeTenABP

Это существует. Не изобретайте велосипед.

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);
    }
}

Эта программа выводит

21 день

Вы захотите добавить проверку того, что годы и месяцы равны 0, или распечатать их тоже, если их нет. Используйте методы getYears и getMonths класса Period.

Как видите, недели автоматически преобразуются в дни. Класс Period не представляет недели внутри страны, только годы, месяцы и дни. Все ваши примеры строк поддерживаются. Вы можете анализировать P1Y (1 год), * ​​1019 * (1 год 6 месяцев), P1Y2M14D (1 год 2 месяца 14 дней), даже P1Y5D, P2M, P1M15D, P35D и конечно P3W и т. д.

Вопрос: Могу ли я использовать java.time на Android?

Да, java.time прекрасно работает на старых и новых устройствах Android. Для этого требуется как минимум Java 6 .

  • В Java 8 и более поздних версиях и на более новых устройствах Android (начиная с уровня API 26) современный API поставляется встроенным. В этом случае импорт из java.time, а не org.threeten.bp.
  • В Java 6 и 7 получите ThreeTen Backport, бэкпорт новых классов (ThreeTen для JSR 310; см. Ссылки внизу).
  • На (более старых) Android используется версия Android ThreeTen Backport. Это называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из org.threeten.bp с подпакетами.

Ссылки

...