首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从RRULE到人类可读文本

从RRULE到人类可读文本
EN

Stack Overflow用户
提问于 2014-07-26 12:17:45
回答 3查看 2.9K关注 0票数 2

我想从RRULE字符串(RFC2445)生成一个人类可读的文本(自然语言)。我搜索了一下,我发现只有一个JavaScript库(rrule.js)可以生成这样的文本。但是我需要Android (Java)的这个功能。

在Java中有像这样的库wrriten吗?如果没有,我听说有几个JavaScript引擎在Java (比如犀牛),但是我非常担心我的安卓应用程序的性能,因为看起来这个引擎有点重。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-01 19:05:49

在内部使用WebViewrrule.js来获得结果。见以下答案:如何从Android调用javascript?

票数 1
EN

Stack Overflow用户

发布于 2017-07-31 21:16:08

与其用不必要的js充实应用程序,不如编写自己的类来帮助您,或者使用我编写的这个类。它适用于我测试过的所有用例,但是如果你发现它有什么问题,请告诉我。它使用JodaTime,但可以根据任何其他时间对象进行调整。它也能够适应本地化(虽然我还没有机会测试它)。如果需要更多语言,只需将它们添加到Strings.init()方法中即可。

代码语言:javascript
复制
package com.rexios.wealthprojection;

import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.ISODateTimeFormat;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by adelory on 7/31/2017.
 */

public class ReadableRRule {

    public static String getReadableRRule(String rrule) throws TextParseException {
        return getReadableRRule(rrule, true);
    }

    public static String getReadableRRule(String rrule, boolean capitalize) throws TextParseException {
        Strings.init(Locale.getDefault().getLanguage());

        HashMap<String, String> attributes = new HashMap<>();
        try {
            String[] attrArray = rrule.replace("RRULE:", "").split("[=;]");

            String key = "";
            String value = "";
            for (String s : attrArray) {
                if (key.isEmpty()) {
                    key = s;
                    continue;
                }
                if (value.isEmpty()) {
                    value = s;
                }

                attributes.put(key, value);
                key = "";
                value = "";
            }

            String interval = "";
            String freq = "";
            String byDay = "";
            String until = "";
            String count = "";
            for (Map.Entry<String, String> entry : attributes.entrySet()) {
                if (entry.getKey().equals("FREQ")) {
                    freq = entry.getValue();
                } else if (entry.getKey().equals("UNTIL")) {
                    until = DateTimeFormat.shortDate().print(ISODateTimeFormat.basicDateTimeNoMillis().parseLocalDate(entry.getValue()));
                } else if (entry.getKey().equals("INTERVAL")) {
                    interval = entry.getValue();
                } else if (entry.getKey().equals("COUNT")) {
                    count = entry.getValue();
                } else if (entry.getKey().equals("BYDAY")) {
                    // TODO: Make this work for monthly stuff
                    byDay = entry.getValue();

                    int num = 0;
                    Matcher matcher = Pattern.compile(".?\\d+").matcher(byDay);
                    if (matcher.find()) {
                        String temp = matcher.group();
                        num = Integer.parseInt(temp);
                        byDay = byDay.replace(temp, "");
                    }

                    boolean abbreviate = true;
                    if (byDay.length() == byDay.replace(",", "").length()) abbreviate = false;
                    byDay = byDay.replace(",", ", ");
                    byDay = byDay.replace("MO", abbreviate ? getShortDayName(0) : getFullDayName(0));
                    byDay = byDay.replace("TU", abbreviate ? getShortDayName(1) : getFullDayName(1));
                    byDay = byDay.replace("WE", abbreviate ? getShortDayName(2) : getFullDayName(2));
                    byDay = byDay.replace("TH", abbreviate ? getShortDayName(3) : getFullDayName(3));
                    byDay = byDay.replace("FR", abbreviate ? getShortDayName(4) : getFullDayName(4));
                    byDay = byDay.replace("SA", abbreviate ? getShortDayName(5) : getFullDayName(5));
                    byDay = byDay.replace("SU", abbreviate ? getShortDayName(6) : getFullDayName(6));

                    if (num != 0) {
                        String numText = "";
                        switch (num) {
                            case -1:
                                numText = Strings.last;
                                break;

                            case 1:
                                numText = Strings.first;
                                break;

                            case 2:
                                numText = Strings.second;
                                break;

                            case 3:
                                numText = Strings.third;
                                break;

                            case 4:
                                numText = Strings.fourth;
                                break;
                        }

                        byDay = "(" + Strings.on + " " + Strings.every + " " + numText + " " + byDay + ")";
                    } else {
                        byDay = Strings.on + " " + byDay;
                    }
                }
            }

            if ((interval.isEmpty() || interval.equals("1")) && byDay.length() - byDay.replace(",", "").length() == 6) {
                freq = "DAILY";
                byDay = "";
            }

            String readableRRule = "";
            switch (freq) {
                case "DAILY":
                    if (interval.isEmpty() || interval.equals("1")) {
                        readableRRule += capitalize ? capitalize(Strings.daily) : Strings.daily;
                    } else {
                        readableRRule += capitalize ? capitalize(Strings.every) : Strings.every;
                        readableRRule += " " + interval + " " + Strings.days;
                    }
                    break;
                case "WEEKLY":
                    if (interval.isEmpty() || interval.equals("1")) {
                        readableRRule += capitalize ? capitalize(Strings.weekly) : Strings.weekly;
                    } else {
                        readableRRule += capitalize ? capitalize(Strings.every) : Strings.every;
                        readableRRule += " " + interval + " " + Strings.weeks;
                    }
                    break;
                case "MONTHLY":
                    if (interval.isEmpty() || interval.equals("1")) {
                        readableRRule += capitalize ? capitalize(Strings.monthly) : Strings.monthly;
                    } else {
                        readableRRule += capitalize ? capitalize(Strings.every) : Strings.every;
                        readableRRule += " " + interval + " " + Strings.months;
                    }
                    break;
                case "YEARLY":
                    if (interval.isEmpty() || interval.equals("1")) {
                        readableRRule += capitalize ? capitalize(Strings.yearly) : Strings.yearly;
                    } else {
                        readableRRule += capitalize ? capitalize(Strings.every) : Strings.every;
                        readableRRule += " " + interval + " " + Strings.years;
                    }
                    break;
            }

            if (!byDay.isEmpty()) {
                readableRRule += " " + byDay;
            }

            if (!until.isEmpty()) {
                readableRRule += "; " + Strings.until + " " + until;
            }

            if (!count.isEmpty()) {
                if (count.equals("1")) {
                    readableRRule += "; " + Strings.four + " " + Strings.one + " " + Strings.time;
                } else {
                    readableRRule += "; " + Strings.four + " " + count + " " + Strings.times;
                }
            }

            return readableRRule;
        } catch (Exception e) {
            e.printStackTrace();
            throw new TextParseException();
        }
    }

    // Get day of week Monday-Sunday (0-6)
    private static String getFullDayName(int day) {
        Calendar c = Calendar.getInstance();
        c.set(2011, 7, 1, 0, 0, 0);
        c.add(Calendar.DAY_OF_MONTH, day);
        return String.format("%tA", c);
    }

    private static String getShortDayName(int day) {
        Calendar c = Calendar.getInstance();
        c.set(2011, 7, 1, 0, 0, 0);
        c.add(Calendar.DAY_OF_MONTH, day);
        return String.format("%ta", c);
    }

    private static String capitalize(String s) {
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    private static class Strings {

        static String daily = "daily";
        static String weekly = "weekly";
        static String monthly = "monthly";
        static String yearly = "yearly";

        static String days = "days";
        static String weeks = "weeks";
        static String months = "months";
        static String years = "years";

        static String every = "every";
        static String on = "on";
        static String until = "until";
        static String four = "for"; // "for" is a reserved word
        static String times = "times";
        static String time = "time";

        static String one = "one";
        static String first = "first";
        static String second = "second";
        static String third = "third";
        static String fourth = "fourth";
        static String last = "last";

        static void init(String language) {
            // TODO: Support different locales
            if (language.equals("es")) {
                daily = "diariamente";
                weekly = "semanal";
                monthly = "mensual";
                yearly = "anual";

                days = "días";
                weeks = "semanas";
                months = "meses";
                years = "años";

                every = "cada";
                on = "en";
                until = "hasta";
                four = "para";
                times = "veces";
                time = "vez";

                one = "una";
                first = "primero";
                second = "segundo";
                third = "tercero";
                fourth = "cuarto";
                last = "último";
            }
        }
    }

    public static class TextParseException extends Exception {
        TextParseException() {
            super();
        }

        TextParseException(String message) {
            super(message);
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2020-08-15 16:58:42

下一个版本的复发性库将有一个have ()函数。在蟒蛇里。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24970931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档