确定字符串是解析前的有效日期 [英] Determine if a String is a valid date before parsing

查看:113
本文介绍了确定字符串是解析前的有效日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的情况,我正在阅读约130K个记录,其中包含作为字符串存储的日期。一些记录包含空白(null),有些包含这样的字符串:'dd-MMM-yy',有些包含这个'dd / MM / yyyy'。



写了一个这样的方法:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆