如何将歧义字符串解析为日期?

问题描述:

我想弄清楚一个“简单”的解析字符串到日期对象中的方法。如何将歧义字符串解析为日期?

该字符串可以是yyyyMMdd,yyyyMMddHHmm或yyyyMMddHHmmSS。

目前,我正在查看字符串的长度,并根据长度创建DateParser。有没有更好的方法来做到这一点?

+5

类似的问题http://stackoverflow.com/questions/5897288/optional-parts-in-simpledateformat –

或者你可以垫你的字符串与零:

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmSS") { 
    @Override 
    public Date parse(String s) throws ParseException { 
    return super.parse((s + "000000").substring(0, 14)); 
    } 
}; 

System.out.println(sdf.format(sdf.parse("20110711182405"))); 
System.out.println(sdf.format(sdf.parse("201107111824"))); 
System.out.println(sdf.format(sdf.parse("20110711"))); 
+0

+1原始解决方案:) –

我会使用SimpleDateFormat类,并根据字符串的长度填充格式模式。除非你有一天有相同长度的字符串,否则这将工作正常。

使用从你的问题的例子:

2011格式7月11日:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); 
Date parsedDate = dateFormat.parse("20110711"); 

格式11日2011年7月1340hrs:

dateFormat = new SimpleDateFormat("yyyyMMddHHmm"); 
parsedDate = dateFormat.parse("201107111340"); 

格式11日2011年7月1340hrs10秒:
(注意,小秒针秒,大写S为毫秒!)

dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); 
parsedDate = dateFormat.parse("20110711134010"); 

查看格式模式字母完整列表的超链接。

+1

你可以请提供一个例子吗?代码应该是什么样子? '新的SimpleDateFormat(“YYYYMMDD”)或'新的SimpleDateFormat(“YYYYMMDDHHMMSS”)? – iliaden

+1

另外,您的链接指向过时的文档。 –

+0

道歉,链接已更新。 – razlebe

您可以使用DateFormatter来解析字符串中的日期。

import java.util.*; 
import java.text.*; 

public class StringToDate 
{ 
public static void main(String[] args) 
{ 
try 
{ 
    String str_date="11-June-07"; 
    DateFormat formatter ; 
    Date date ; 
    formatter = new SimpleDateFormat("yyyy-MM-dd"); 
    date = (Date)formatter.parse(str_date); 

    } 
    catch (ParseException e) 
    { 
    System.out.println("Exception :"+e); 
    } 
} 
} 

您可以更改图案,但是您想要反映您的需求。

+2

是的。但在我的情况下,我需要3个单独的DateFormatters,直到其中一个工程... – iliaden

我会尽你所能,看着字符串的长度,并创建一个合适的SimpleDateFormat实例。

SimpleDateFormat getFormatFor(String dateString){ 
    if (dateString.length() == 8 ) return new SimpleDateFormat("yyyyMMdd"); 
    if (dateString.length() == 14) return new SimpleDateFormat("yyyyMMddHHmmss"); 
    // you got a bad input... 
} 

注意这些不是线程安全的,所以您应该每次创建一个新线程。

你仍然可以使用“特殊”的解析器(如你所说),并把它们连: 举例来说,你仍然可以有一个DateHourMinSecParser(用于yyyyMMddHHmmSS),一个DateHourMinParser(为yyyyMMddHHmm)和DateParser(用于yyyyMMdd)所有他们实施相同的接口:

public interface GenericDateParser { 
Date parseDate(String input) throws IllegalArgumentException; 
} 

eg

public class DateHourMinSecParser implements GenericDateParser { 
... 
    public Date parseDate(String input) throws IllegalArgumentException { 
    ... 
    } 
} 

但这些类中的每一个实际上会采取一个参数另一个GenericDateParser - 的想法是,每个解析器将首先解析日期本身试试,如果解析(或一些内部的检查 - 例如字符串长度)失败,然后将它传递给链中的下一个解析器,直到链中没有更多解析器(在这种情况下,它会抛出异常,或链中的一个成员将返回一个值):

public class DateHourMinSecParser implements GenericDateParser { 
    private GenericDateParser chained; 

    public DateHourMinSecParser(GenericDateParser chained) { 
     this.chained = chained; 
    } 

    public Date parseDate(String input) throws IllegalArgumentException { 
     if(!internalChecks()) { //chain it up 
     if(chained == null) throw new IllegalArgumentException("Don't know how to parse " + input); 
     } 
     //internal checks passed so try to parse it and return a Date or throw exception 
     ... 
    } 
} 

,你会初始化它们:

GenericDateParser p = new DateHourMinSecParser(new DateHourMinParser(new DateParser(null))); 

,然后只用顶层之一:

Date d = p.parse('20110126');