【问题标题】:How to parse ambiguous String into Date?如何将不明确的字符串解析为日期?
【发布时间】:2011-10-02 22:50:45
【问题描述】:

我正在尝试找出一种将字符串解析为日期对象的“简单”方法。

字符串可以是 yyyyMMdd、yyyyMMddHHmm 或 yyyyMMddHHmmSS。

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

【问题讨论】:

标签: java string parsing date


【解决方案1】:

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

使用您问题中的示例:

2011 年 7 月 11 日格式化:

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

格式化 2011 年 7 月 11 日 1340 小时:

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

格式化 2011 年 7 月 11 日 1340 小时 10 秒:
(注意,小 s 代表秒,大写 S 代表毫秒!)

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

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

【讨论】:

  • 你能举个例子吗?代码应该是什么样的? new SimpleDateFormat ( "YYYYMMDD" ) 或 `new SimpleDateFormat ("YYYYMMDDHHMMSS")?
【解决方案2】:

您可以使用 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);  
  }  
 }
} 

您可以根据自己的需要更改模式。

【讨论】:

    【解决方案3】:

    我会照你做,查看字符串的长度,并创建一个合适的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...
    }
    

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

    【讨论】:

      【解决方案4】:

      您仍然可以使用“专业”解析器(如您所建议的那样)并将它们链接起来: 例如,您仍然可以拥有一个DateHourMinSecParser(对于yyyyMMddHHmmSS)、一个DateHourMinParser(对于yyyyMMddHHmm)和一个DateParser(对于yyyyMMdd),它们都实现了相同的接口:

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

      例如

      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' );
      

      【讨论】:

        【解决方案5】:

        或者你可以用零填充你的字符串:

        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")));
        

        【讨论】:

          猜你喜欢
          • 2012-05-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-28
          • 1970-01-01
          • 2017-06-22
          • 1970-01-01
          相关资源
          最近更新 更多