我需要能够将日期的所有可能的字符串表示转换为Date对象。我知道这不是一项微不足道的任务,我主要是寻求指导,因为我认为没有“单线”解决方案。
仅有一个可能的输入类的当前示例:return new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH).parse(input);
为了澄清我的问题,这里有一些可能的字符串输入:
数据是由第三方移交的,所以我对此无能为力。我有一些关于检查分隔符是什么的想法,并根据它选择正确的格式。
感谢任何帮助。
问候。
编辑:我可以访问用户的区域设置,这样我就可以实际区分日期和月份部分。或者换句话说,我可以访问日期的区域设置。
答案 0 :(得分:1)
第一个想法可能是检测非数字和非字母字符。这些字符分隔日期中的月,日和年。在你的例子中,这些是' - ',''和'。'。
接下来,根据检测到的分隔符分割字符串。
这会在第一种情况下给你:[“30”,“08”,“2011”。
然后我们可以检查年份是第一个还是最后一个。这可以通过检查位数来完成。如果numDigits == 4那么你就知道哪一年是年份。否则你可以检查范围,是不是[1,31]然后又是一年。如果他们都在[1,31],那么我认为没有明确的决定方式。 (也许你更了解一年的可能性?)
最后是中间的字符串。在那里,您只需检查它是否包含字母字符或数字。
答案 1 :(得分:1)
Uglier代码比我想象的还要多。所以我会给它。 拆分令牌,填充3个日期组件。 人们仍然需要找到给定语言环境的那些组件的顺序:Mdy,dMy。
public class DateIn {
public static void main(String[] args) {
String[] dates = {
"30-08-2011",
"25.06.2011",
"15 Juni 2011",
"01-07-11",
"19-9-2011",
};
DateIn in = new DateIn();
Locale locale = Locale.US;
for (String date : dates) {
try {
Date d = in.read(date, locale);
System.out.printf("%s -> %s%n", date,
new SimpleDateFormat("yyyy-MM-dd").format(d));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
}
private Date read(String date, Locale locale)
throws IllegalArgumentException {
final String[] ymdFormatters = { "y", "M", "d" };
final int[] ymdGetters = { Calendar.YEAR, Calendar.MONTH,
Calendar.DAY_OF_MONTH };
String[] tokens = date.split("\\W+");
final int Y = 0;
final int M = 1;
final int D = 2;
int[] ymdValues = new int[3];
for (String token : tokens) {
if (token.matches("\\d+\\pL+")) { // 1st, 2nd, 3rd, 4th, 1e, ...
token = token.replaceAll("\\pL+", "");
ymdValues[D] = Integer.parseInt(token);
} else if (token.matches("\\d+")) {
int n = Integer.parseInt(token);
if (n > 31) {
ymdValues[Y] = n;
} else if (n > 12) {
ymdValues[D] = n;
} else {
// Locale dependent order.
if (ymdValues[M] == 0) {
ymdValues[M] = n;
} else if (ymdValues[D] == 0) {
ymdValues[D] = n;
} else if (ymdValues[Y] == 0) {
ymdValues[Y] = n;
}
}
} else if (!token.isEmpty()) {
for (int md = M; md <= D; ++md) {
String fmt = "";
for (int i = 0; i < 4; ++i) {
fmt += ymdFormatters[md];
SimpleDateFormat sdf = new SimpleDateFormat(fmt);
sdf.setLenient(true);
try {
Date dt = sdf.parse(token);
Calendar cal = Calendar.getInstance(locale);
cal.setTime(dt);
int n = cal.get(ymdGetters[md]);
if (md == M) {
++n; // To 1-based
}
ymdValues[md] = n;
break;
} catch (ParseException e) {
//continue;
}
}
}
}
}
Calendar calendar = Calendar.getInstance(locale);
for (int md = Y; md <= D; ++md) {
int n = ymdValues[md];
if (n == 0) {
throw new IllegalArgumentException("Missing "
+ ymdFormatters[md] + " part in " + date);
}
if (md == Y) {
if (n < 100)
n += (calendar.get(Calendar.YEAR) / 100) * 100;
} else if (md == M) {
--n; // Calendar's month is 0-based.
}
calendar.set(ymdGetters[md], n);
}
return calendar.getTime();
}
}
答案 2 :(得分:0)
您可以尝试将字符串拆分为其组成部分(天,月,年)并单独解析它们。
例如:
String input = 30-08-2011;
if (input.indexOf("-") == -1)
return;
else
String day = index.substring(0, selected.indexOf("-"));
那天,可以单独解析。然后重复该过程的月份和年份。然后,您不必担心日期组件之间的格式。