从字符串解析日期/时间?
我想创建一个程序来解析一个字符串中有意义的日期和时间。我希望能够给以下几种输入,并创建一个日期/时间对象:从字符串解析日期/时间?
5 o'clock
5 p.m.
5 a.m.
5
530
530 a.m.
530 p.m.
Tuesday at [insert any above string here]
the 30th at [same as above]
May 12th at [same as above]
today at [same as above]
tomorrow at [same as above]
不包含日/日期可以假设今天是任何字符串,任何时间没有上午/下午指定可以被认为是在上午9点到下午8点59分之间发生。 我很快就意识到什么乱七八糟的在写代码的这一部分后成为:
private void createEvent(String phrase) {
int hour;
int day = 0;
String dayOfWeek = "";
if (phrase.contains("o'clock")) {
hour = Integer.parseInt(phrase.substring(phrase.indexOf("o'clock")-3, phrase.indexOf("o'clock")-1).trim());
out.write(""+hour);
}
if (phrase.contains("tomorrow"))
day = (Calendar.DAY_OF_WEEK % 7)+1;
if (phrase.contains("sunday") || day == 1) {
dayOfWeek = "Sunday"; day = 1; }
else if (phrase.contains("monday") || day == 2) {
dayOfWeek = "Monday"; day = 2; }
else if (phrase.contains("tuesday") || day == 3) {
dayOfWeek = "Tuesday"; day = 3; }
else if (phrase.contains("wednesday") || day == 4) {
dayOfWeek = "Wednesday"; day = 4; }
else if (phrase.contains("thursday") || day == 5) {
dayOfWeek = "Thursday"; day = 5; }
else if (phrase.contains("friday") || day == 6) {
dayOfWeek = "Friday"; day = 6; }
else if (phrase.contains("saturday") || day == 7) {
dayOfWeek = "Saturday"; day = 7; }
else {
dayOfWeek = "Today"; day = 0; }
}
任何人都可以提供一些方向?
你可以使用日期格式
String now = new Date().toString();
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date date = format.parse(now);
也许你可以建立提前几个格式,然后比较分析的日期。
检查教程这里:http://www.xyzws.com/Javafaq/how-to-use-simpledateformat-class-formating-parsing-date-and-time/142
不会解析“a.m.”或“下午”。 “明天”呢? – MadProgrammer 2013-05-13 06:00:26
如果字符串格式没有限制,编写代码来处理所有情况是不可能的。如果你想解析用户输入的所有内容,它将成为关于自然语言处理的一个问题... – ltebean 2013-05-13 06:09:20
然后说尽可能多的 – MadProgrammer 2013-05-13 06:15:28
下打破你的问题转化为可管理的块...
我会通过提供这,因为你需要,你可以添加新的格式化的手段开始。
我也试着找到重用现有的代码。时间对于你的问题是一个非常一致的方面。
这将导致我提供某种形式的统一格式工厂的概念(使管理更容易),但个性化需求分解成更小的可管理的块
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class CustomDateFormatter {
public static void main(String[] args) {
new CustomDateFormatter();
}
public CustomDateFormatter() {
String values[] = new String[]{
"5 o'clock",
"5 p.m.",
"5 a.m.",
"5",
"530",
"530 a.m.",
"530 p.m.",};
for (String value : values) {
System.out.println(value + " = " + CustomFormatFactory.format(value));
}
}
public static class CustomFormatFactory {
private static List<CustomFormat> formatters = new ArrayList<>();
public static Date format(String value) {
Date date = null;
for (CustomFormat format : formatters) {
if (format.canFormat(value)) {
date = format.format(value);
if (date != null) {
break;
}
}
}
return date;
}
protected static boolean formatTime(String value, Calendar cal) {
boolean formatted = false;
if (Character.isDigit(value.charAt(0))) {
formatted = true;
StringBuilder timePart = new StringBuilder(4);
int index = 0;
while (index < value.length() && Character.isDigit(value.charAt(index))) {
timePart.append(value.charAt(index));
index++;
}
int hour = 0;
int min = 0;
if (timePart.length() < 3) {
hour = Integer.parseInt(timePart.toString());
} else {
hour = Integer.parseInt(timePart.substring(0, timePart.length() - 2));
min = Integer.parseInt(timePart.substring(timePart.length() - 2, 3));
}
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.MILLISECOND, 0);
String sufix = value.substring(timePart.length()).trim();
if ("p.m.".equalsIgnoreCase(sufix) || "pm".equalsIgnoreCase(sufix)) {
cal.add(Calendar.HOUR, 12);
}
}
return formatted;
}
static {
formatters.add(new SimpleTimeFormat());
}
}
public static interface CustomFormat {
public boolean canFormat(String value);
public Date format(String value);
}
public static class SimpleTimeFormat implements CustomFormat {
@Override
public boolean canFormat(String value) {
return format(value) != null;
}
@Override
public Date format(String value) {
Date date = null;
Calendar cal = Calendar.getInstance();
if (CustomFormatFactory.formatTime(value, cal)) {
date = cal.getTime();
}
return date;
}
}
}
对于扩展的日期格式,我会提取日期部分,根据日期生成Calendar
,将时间分区提取为单独的String
,并使用CustomFormatFactory.formatTime
方法来格式化时间,从而使您不必每次重新编码它。
同样,日期格式化器可以在内部简单地拥有一个时间格式化器的实例,或者您可以将工厂设置为具有多个格式方法,一个需要时间值并通过可用时间格式化器循环......这会是我个人的选择;)
我会专注于每个案件seperatly,也许创建一个简单的'格式化工具'的基本目的。将它们全部添加到*'FormatFactory'中。这将允许您根据需要增加可能的格式化器数量(或者在需要时排除一些格式器) – MadProgrammer 2013-05-13 05:42:24
您的字符串中可能还有其他什么?整个字符串是否与时间有关,还是可能包含其他信息?例如:“我会在五点钟在车站接你” – GHC 2013-05-13 05:45:23