从字符串中解析日期,格式为:dd/MM/yyyy [到 dd/MM/yyyy]。

6
我在思考使用Java解析具有以下格式的字符串的最佳方法:dd/MM/yyyy [to dd/MM/yyyy]。带有[]的字符串是可选的,dd表示日期的2位数字表示形式,MM表示月份的2位数字表示形式,yyyy表示年份的4位数字表示形式。

更新

谢谢大家的快速回复,但我忘了告诉你们[]是表示可选的符号,在字符串中没有[],样例字符串可能如下:

  • 22/01/2010
  • 22/01/2010 to 23/01/2010
  • null

目前我写的代码是这样的,虽然能用但很丑 =(

String _daterange = (String) request.getParameter("daterange");
    Date startDate = null, endDate = null;
    // Format of incoming dateRange is 
    if (InputValidator.requiredValidator(_daterange)) {
        String[] _dateRanges = _daterange.toUpperCase().split("TO");
        try {
            startDate = (_dateRanges.length > 0) ? sdf.parse(_dateRanges[0]) : null;
            try{
                endDate = (_dateRanges.length > 1) ? sdf.parse(_dateRanges[1]) : null;
            }catch(Exception e){
                endDate = null;
            }
        } catch (Exception e) {
            startDate = null;
        }
    }

对于新读者,我建议不要使用DateSimpleDateFormat。这些类设计得很差,而且早已过时,后者尤其麻烦。相反,应该使用来自java.time,现代Java日期和时间APILocalDateDateTimeFormatter。有关详细信息,请参见Basil Bourque的答案 - Ole V.V.
4个回答

24

使用java.text.DateFormatjava.text.SimpleDateFormat来进行操作。

DateFormat sourceFormat = new SimpleDateFormat("dd/MM/yyyy");
String dateAsString = "25/12/2010";
Date date = sourceFormat.parse(dateAsString);

更新:

如果你有两个日期藏在那个字符串里面,你需要将它们分成两部分。我认为其他人已经指出了"split"的想法。我只是在空格处把它们分开,然后把"TO"扔掉。

不要担心效率问题。你的应用程序很可能存在比这更糟糕的低效问题。让它正确工作,只有当性能分析告诉你这段代码是最严重的问题时,再进行重构。


我不确定DateFormat类是否能够解析带有两个日期的字符串。他可能需要先手动检查长度并拆分它。 - ZeissS
感谢您的快速回复。 我尝试了类似的方法,但我认为它不够高效。 首先,我使用String[] token = String.split("TO"); 然后,如果token.length > 0, sdf.parse(token[0]); 如果token.length > 1, sdf.parse(token[1]); - Yijinsei

1

tl;dr

LocalDate.parse( 
    "22/01/2010" , 
    DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) 
)

…more…

// String input is:
// (a) long: "22/01/2010 to 23/01/2010". 
// (b) short: "22/01/2010".
// (c) null.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;

if( input.length() == 24 ) {           // Ex: "22/01/2010 to 23/01/2010"
    List<LocalDate> lds = new ArrayList<>( 2 );
    String[] inputs = input.split( " to " );
    for( String nthInput : inputs ) {
        LocalDate ld = LocalDate.parse( nthInput , f ) ;
        lds.add( ld );
    }
    … // Do what you want with `LocalDate` objects collection.

} else if( input.length() == 10 ) {    // Ex: "22/01/2010"
    LocalDate ld = LocalDate.parse( input , f ) ;
    … // Do what you want with `LocalDate` object.

} else if( null == input ) {
    … // Decide what you want to do for null input.

} else {
    System.out.println( "Unexpected input: " + input ) ;
}

请查看在IdeOne.com上运行的代码示例

使用java.time

其他答案使用已经过时的日期时间类,现在被java.time类所取代。

至于处理多种类型的字符串,请查看字符串的长度。

if( input.length() == 10 ) { … }

如果很长,就按照4个字符的子字符串“ to ”进行分割。
String[] inputs = "22/01/2010 to 23/01/2010".split( " to " );

解析日期字符串为LocalDate
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "22/01/2010" , f );

关于 java.time

java.time 框架内置于 Java 8 及以上版本。这些类取代了老旧的 遗留 日期时间类,如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现已进入维护模式,建议迁移到 java.time 类。

了解更多,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。无需字符串,无需 java.sql.* 类。

如何获取 java.time 类?

ThreeTen-Extra项目是扩展java.time的附加类。该项目是java.time可能未来增加的可行性试验场。您可以在此处找到一些有用的类,例如Interval, YearWeek, YearQuarter更多


0

这样做应该就可以了:

String input = "02/08/2010 [to 31/12/2010]";
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date d  = format.parse(input.split(" ")[0]);
System.out.println(d) ;

0

你可以像这样做 -

String input = "02/08/2010 [to 31/12/2010]";
    java.text.DateFormat format = new java.text.SimpleDateFormat("dd/MM/yyyy");
    java.util.Date d = null;
    try {
        d = format.parse(input.split(" ")[0]);
    } catch (java.text.ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(d) ;

如果字符串中没有 [],input.split(" ")[0] 仍将返回第一个字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接