gpt4 book ai didi

java - 人类可读文本的 RRULE

转载 作者:行者123 更新时间:2023-11-29 19:36:11 27 4
gpt4 key购买 nike

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

有这样用Java写的库吗?如果没有,我听说过一些 Java 中的 JavaScript 引擎(例如 Rhino),但我非常担心我的 Android 应用程序性能,因为看起来这些引擎有点重。

最佳答案

与其使用不必要的 js 使您的应用程序膨胀,您可以编写自己的类来为您完成,或者使用我编写的这个类。它适用于我测试的所有用例,但如果您发现它有问题,请告诉我。它使用 JodaTime,但可以针对任何其他时间对象进行调整。它还能够适应本地化(尽管我还没有机会测试它)。如果您需要更多语言,只需将它们添加到 Strings.init() 方法即可。

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

关于java - 人类可读文本的 RRULE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24970931/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com