确定字符串是解析前的有效日期 [英] Determine if a String is a valid date before parsing
问题描述
写了一个这样的方法:
public Date parsedate(String date){
if(date! == null){
try {
1.使用'dd-MMM-yy'作为模式
创建一个SimpleDateFormat对象2.解析日期
3.返回解析date
} catch(ParseException e){
try {
1.使用'dd / MM / yyy'作为模式创建一个SimpleDateFormat对象
2.解析日期
3. return parsed date
} catch(ParseException e){
return null
}
}
} else {
return null
}
}
所以你可能已经发现了这个问题。 我正在使用try .. catch作为我的逻辑的一部分。这将是更好的是我可以确定之前的String实际上包含一个可解析的日期在某种格式,然后尝试解析它。
那么,有没有一些API或库这可以帮助吗?我不介意编写几个不同的Parse类来处理不同的格式,然后创建一个工厂来选择正确的6,但是如何确定哪一个?
谢谢
请参阅 Java中的懒惰错误处理,了解如何使用选项
类型来消除try / catch块的概述。 / p>
功能Java 是您的朋友。 / p>
本质上,您想要做的是将日期解析包装在不抛出任何东西的函数中,但在返回类型中指示解析是否成功。例如:
import fj.F;进口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();
}
}
});
好的,现在你有一个可重用的日期解析器,不会抛出任何东西,返回值为 Option.None
的值。以下是您如何使用它:
import fj.data.List;
import static fj.data.Stream.stream;
import static fj.data.Option.isSome_;
....
public选项< Date> parseWithPatterns(String s,Stream< String>模式){
return stream(s).apply(patterns.map(parseDate))。find(isSome_());
}
这将给你解析与匹配的第一个模式的日期,或值类型为Option.None,这是类型安全而null不是。
如果你想知道什么 Stream
是... 这是一个懒惰的列表。这确保您在第一个成功之后忽略模式。不需要做太多的工作。
调用这样的功能:
for(Date d:parseWithPatterns(someString,stream(dd / MM / yyyy,dd-MM-yyyy)){
//在这里做一些事情
}
或...
选项< Date> d = parseWithPatterns(someString,
stream(dd / MM / yyyy,dd-MM-yyyy));
if(d.isNone ()){
//处理两种模式匹配的情况
}
else {
//使用d.some()执行某些操作
}
I have this situation where I am reading about 130K records containing dates stored as String fields. Some records contain blanks (nulls), some contain strings like this: 'dd-MMM-yy' and some contain this 'dd/MM/yyyy'.
I have written a method like this:
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
}
}
So you may have already spotted the problem. I am using the try .. catch as part of my logic. It would be better is I can determine before hand that the String actually contains a parseable date in some format then attempt to parse it.
So, is there some API or library that can help with this? I do not mind writing several different Parse classes to handle the different formats and then creating a factory to select the correct6 one, but, how do I determine which one?
Thanks.
See Lazy Error Handling in Java for an overview of how to eliminate try/catch blocks using an Option
type.
Functional Java is your friend.
In essence, what you want to do is to wrap the date parsing in a function that doesn't throw anything, but indicates in its return type whether parsing was successful or not. For example:
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();
}
}
});
OK, now you've a reusable date parser that doesn't throw anything, but indicates failure by returning a value of type Option.None
. Here's how you use it:
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_());
}
That will give you the date parsed with the first pattern that matches, or a value of type Option.None, which is type-safe whereas null isn't.
If you're wondering what Stream
is... it's a lazy list. This ensures that you ignore patterns after the first successful one. No need to do too much work.
Call your function like this:
for (Date d: parseWithPatterns(someString, stream("dd/MM/yyyy", "dd-MM-yyyy")) {
// Do something with the date here.
}
Or...
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()
}
这篇关于确定字符串是解析前的有效日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!