Java简单日期格式 - dd / MM / yy v / s dd / MM / yyyy

时间:2017-07-05 03:55:34

标签: java simpledateformat datetime-parsing

我需要将String解析为dd/MM/YY hh:mm:ss格式。

假设String的值为09/06/17 05:59:59,那么它应该被解析,但如果String的值为09/06/2017 05:59:59,那么这也是一种有效的格式并且会被解析但是在我的要求,应该为后者抛出一个解析异常。

代码:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateDemo {

    public static void main(String[] args) {

        String line=" 09/06/17 05:59:59 20170609IT36701706080107 42 103 Output USD 970.20 IT3670";
        //String line=" 09/06/2017 05:59:59 20170609IT36701706080107 42 103 Output USD 970.20 IT3670";

        String dt=null;
        dt=line.substring(1, 19);

        SimpleDateFormat org_format = new SimpleDateFormat("dd/MM/YY hh:mm:ss");
        SimpleDateFormat tgt_format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        try {
              dt=line.substring(1, 19);

              System.out.println(dt);
              Date date = org_format.parse(dt);
              System.out.println(date);

              String tgt_date=tgt_format.format(date);
              System.out.println(tgt_date);
         } catch (ParseException e) {
              System.out.println(line);
         }
    }
}

问题 - 在代码,未注释的行变量和注释行变量中,两者都成功地给出了结果。但是注释行应该抛出可解析的异常,因为它是模式dd/MM/yyyy,而不是dd/MM/yy

fmt.setLenient(false)无效。

我正在使用Java 7.没有选择使用Java 8或更高版本,因此无法使用java.time

3 个答案:

答案 0 :(得分:2)

  

没有使用java 8或更高版本的选项,因此无法使用java.time

Java 8日期和时间类已被反向移植到Java 6和7,所以是的,您可以在Java 7中使用它们。获取ThreeTen Backport。这也是未来的投资:如果最终升级到Java 8或9,您只需要修改import声明,您的代码就可以使用java.time类。

所以我建议你抛弃过时的课程SimpleDateFormatDateSimpleDateFormat非常典型地在您需要异常的情况下给出结果(通常是不正确的结果)。如您所述,有时org_format.setLenient(false);会有所帮助,但在您的情况下则不然。

使用ThreeTen Backport:

    DateTimeFormatter originalFormat = DateTimeFormatter.ofPattern("dd/MM/uu HH:mm:ss");
    ParsePosition pos = new ParsePosition(1); // skip leading space
    LocalDateTime ldt = LocalDateTime.from(originalFormat.parse(line, pos));

这将您的行解析为2位数年份

2017-01-02 05:59:59

对于具有4位数年份的行,“在我的要求中,应该抛出解析异常”,我们得到

  

线程“main”中的异常java.time.format.DateTimeParseException:   文本'09/06/2017 05:59:59 20170609IT36701706080107 42 103输出美元   ......'无法在索引9处解析

它指的是索引9,它位于17中的2017,也就是说,当一年中的第三个数字只是两位数的时候。

要注意几点:

  • 在格式模式中使用大写HH表示小时(小hh小时为AM或PM,仅适用于AM / PM参与者)。使用年份小写,uuyy(不是大写YY,它是基于周的年份,仅对周数有用)。顺便说一句,再次SimpleDateFormat让你逃脱这些错误,有时会给你不正确的结果;现代类将通过抛出异常来反对。
  • 我的代码将解析为2000年到2099年的一年。请检查这是否是您想要的。您可能希望施加额外的限制,例如,日期时间应该是过去且不超过5年,以进行增强验证。你知道的比我好。

转换为目标格式:

    DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    String targetDate = ldt.format(targetFormat);

使用前一行的结果是

2017-01-02 05:59:59

答案 1 :(得分:0)

您可以使用正则表达式来检查年份是否包含4位数,如果是,则抛出新的ParseException。该计划是:

public static void main(String[] args) throws ParseException {

        String date = "09/06/17 05:59:59";

        if (date.matches("\\d{1,2}[/.-]\\d{1,2}[/.-]\\d{4} .*"))
            throw new ParseException("date has wrong format");
        else {

        }

    }

答案 2 :(得分:0)

正则表达式匹配任何这些日期格式

String regex = "^(([0]?[1-9]|1[0-2])/([0-2]?[0-9]|3[0-1])/[1-2]\d{3}) (20|21|22|23|[0-1]?\d{1}):([0-5]?\d{1})$";
Pattern pattern = Pattern.compile(regex);

Matcher matcher = pattern.matcher("09/06/17 05:59:59");

if(matcher.matches()){
    //your next code
}