Mor*_*ter 13 java parsing date
我有这种情况,我正在阅读包含存储为字符串字段的日期的130K记录.有些记录包含空格(nulls),有些包含这样的字符串:'dd-MMM-yy',有些包含'dd/MM/yyyy'.
我写了一个像这样的方法:
public Date parsedate(String date){
if(date !== null){
try{
1. create a SimpleDateFormat object using 'dd-MMM-yy' as the pattern
2. parse the date
3. return the parsed date
}catch(ParseException e){
try{
1. create a SimpleDateFormat object using 'dd/MM/yyy' as the pattern
2. parse the date
3. return parsed date
}catch(ParseException e){
return null
}
}
}else{
return null
}
}
Run Code Online (Sandbox Code Playgroud)
所以你可能已经发现了这个问题.我正在使用try .. catch作为我逻辑的一部分.最好是我可以事先确定String实际上包含某种格式的可解析日期然后尝试解析它.
那么,是否有一些API或库可以帮助解决这个问题?我不介意写几个不同的Parse类来处理不同的格式,然后创建一个工厂来选择正确的6,但是,我该如何确定哪一个?
谢谢.
在逻辑中使用try-catch不要太费劲:这是Java强迫你这样做的一种情况,所以你不能做很多事情.
但在这种情况下你可以改用DateFormat.parse(String, ParsePosition).
有关如何使用类型消除try/catch块的概述,请参阅Java中的延迟错误处理Option.
功能Java是你的朋友.
本质上,您要做的是将日期解析包装在不抛出任何内容的函数中,但在其返回类型中指示解析是否成功.例如:
import fj.F; import fj.F2;
import fj.data.Option;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import static fj.Function.curry;
import static fj.Option.some;
import static fj.Option.none;
...
F<String, F<String, Option<Date>>> parseDate =
curry(new F2<String, String, Option<Date>>() {
public Option<Date> f(String pattern, String s) {
try {
return some(new SimpleDateFormat(pattern).parse(s));
}
catch (ParseException e) {
return none();
}
}
});
Run Code Online (Sandbox Code Playgroud)
好的,现在你有一个可重用的日期解析器,它不会抛出任何东西,但是通过返回一个类型的值来指示失败Option.None.以下是您使用它的方式:
import fj.data.List;
import static fj.data.Stream.stream;
import static fj.data.Option.isSome_;
....
public Option<Date> parseWithPatterns(String s, Stream<String> patterns) {
return stream(s).apply(patterns.map(parseDate)).find(isSome_());
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供使用匹配的第一个模式解析的日期,或者类型为Option.None的值,这是类型安全的,而null则不是.
如果你想知道是什么Stream...... 这是一个懒惰的清单.这可确保您在第一次成功之后忽略模式.不需要做太多工作.
像这样调用你的函数:
for (Date d: parseWithPatterns(someString, stream("dd/MM/yyyy", "dd-MM-yyyy")) {
// Do something with the date here.
}
Run Code Online (Sandbox Code Playgroud)
要么...
Option<Date> d = parseWithPatterns(someString,
stream("dd/MM/yyyy", "dd-MM-yyyy"));
if (d.isNone()) {
// Handle the case where neither pattern matches.
}
else {
// Do something with d.some()
}
Run Code Online (Sandbox Code Playgroud)
您可以利用正则表达式来确定字符串所处的格式,以及它是否与任何有效格式匹配.像这样的东西(未经测试):
(哎呀,我在检查你正在使用的语言之前用C#编写过这个.)
Regex test = new Regex(@"^(?:(?<formatA>\d{2}-[a-zA-Z]{3}-\d{2})|(?<formatB>\d{2}/\d{2}/\d{3}))$", RegexOption.Compiled);
Match match = test.Match(yourString);
if (match.Success)
{
if (!string.IsNullOrEmpty(match.Groups["formatA"]))
{
// Use format A.
}
else if (!string.IsNullOrEmpty(match.Groups["formatB"]))
{
// Use format B.
}
...
}
Run Code Online (Sandbox Code Playgroud)