- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想从 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/
表架构 DROP TABLE bla; CREATE TABLE bla (id INTEGER, city INTEGER, year_ INTEGER, month_ INTEGER, val I
我需要拆分字符串/或从具有以下结构的字符串中获取更容易的子字符串。 字符串将来自 window.location.pathname 或 window.location.href,看起来像 text/n
每当将对象添加到数组中时,我都会尝试更新 TextView ,并在 TextView 中显示该文本,如下所示: "object 1" "object 2" 问题是,每次将新对象添加到数组时,它都会覆盖
我目前正在寻找使用 Java 读取网站可见文本并将其存储为纯文本字符串的方法。 换句话说,我想转换成这样: Hello stupid World进入“ Hello World ” 或者类似的东西 Un
我正在尝试以文本和 HTML 格式发送电子邮件,但无法正确发送正确的 header 。特别是,我想设置 Content-Type header ,但我找不到如何为 html 和文本部分单独设置它。 这
我尝试了上面的代码,但我无法绑定(bind)文本,我怎样才能将资源内部文本 bloc
我刚刚完成了 Space Shooter 教程,由于没有 GUIText 对象,所以我创建了 UI.Text 对象并进行了相应的编码。它在统一播放器中有效,但在构建 Web 应用程序后无效。我花了一段
我有这个代码: - (IBAction)setButtonPressed:(id)sender { NSUserDefaults *sharedDefaults = [[NSUserDefau
抱歉标题含糊不清,但我想不出我想在标题中做什么。无论如何,对于图像上的文本,我使用了 JLabel 文本并将其添加到图标中。 JLabel icon = new JLabel(new Imag
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我在将 Twitter 嵌入到我从 HTML 5 转换的 wordpress 运行网站时遇到问题。 我遇到的问题是推文不是我的自定义字体... 这是我无法使用任何 css 定位的 HTML 代码,我正
我正在尝试找到解决由于使用以下形式的代码而导致的冗余字符串连接问题的最佳方法: logger.debug("Entering loop, arg is: " + arg) // @1 在大多数情况下,
我写了这个测试 @Test public void removeRequestTextFromRouteError() throws Exception { String input = "F
我目前正在创建一个正则表达式来拆分所有匹配以下格式的字符串:&[文本],并且需要获取文本。字符串可能类似于:something &[text] &[text] everything &[text] 等
有没有办法将标题文本从一个词变形为另一个词,同时保留两个词中使用的字母?我看过的许多 css 文本动画大多是视觉的,很少有旋转整个单词的。 我想要做的是从一个词过渡,例如“BEACH”到“CHANGE
总结matplotlib绘图如何设置坐标轴刻度大小和刻度。 上代码: ?
我在容器 (1) 中创建了容器 (2)。你能帮忙如何向容器(1)添加文本吗?下面是我的代码 return Scaffold( body: Padding( padding: c
我似乎找不到任何人或任何人这样做过。我试图限制我们使用的图像数量,并想创建一个带有渐变作为其“颜色”的文本,并在其周围设置渐变轮廓/描边 到目前为止,我还没有看到任何将两者结合在一起的东西。 我可以自
我正在为视频游戏暗黑破坏神 2 使用 discord.py 构建一个不和谐机器人。其中一项功能要求机器人从暗黑破坏神 2 屏幕截图中提取项目的名称和属性。我目前正在为此使用 pytesseract,但
我很难弄清楚如何旋转 strip.text theme 中的属性来自 ggplot2 .我使用的是 R 版本 3.4.2 和 ggplot2 版本 2.2.1。 以下是 MWE 的数据。 > dput
我是一名优秀的程序员,十分优秀!