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

时间:2023-01-14 14:33:05

I need to parse a String into dd/MM/YY hh:mm:ss format.

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

Suppose if a String has value 09/06/17 05:59:59 then it should be parsed but if a String has value 09/06/2017 05:59:59 then this is also a valid format and getting parsed but in my requirement, a parse exception should be thrown for the later.

假设一个字符串有值09/06/17 05:59:59然后它应该被解析,但如果一个字符串有价值09/06/2017 05:59:59然后这也是一个有效的格式并得到解析但在我的要求,应该为后者抛出一个解析异常。

Code:

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

Problem - In the code, uncommented line variable and commented line variable, both are giving result successfully. but the commented line should throw parsable exception as it's the pattern dd/MM/yyyy, not dd/MM/yy.

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

fmt.setLenient(false) is not working.

fmt.setLenient(false)无效。

I'm using Java 7. Don't have option to use Java 8 or later so can't use java.time.

我正在使用Java 7.没有选择使用Java 8或更高版本,所以不能使用java.time。

3 个解决方案

#1


2  

Don't have option to use java 8 or later so cant use java.time

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

The Java 8 date and time classes have been backported to Java 6 and 7, so yes, you can use them in your Java 7. Get ThreeTen Backport. This is also the futureproof investment: if and when eventually you upgrade to Java 8 or 9, you will only have to modify your import declarations and your code will work with the java.time classes.

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

So I recommend you throw the outdated classes SimpleDateFormat and Date over the shoulder. It’s very typical for SimpleDateFormat to give you a result (very often an incorrect one) in a situation where you would want an exception. As you noted, sometimes org_format.setLenient(false); helps, but not in your case.

所以我建议你抛弃过时的类SimpleDateFormat和Date。在您想要异常的情况下,SimpleDateFormat非常典型地为您提供结果(通常是不正确的结果)。如你所述,有时org_format.setLenient(false);有帮助,但不是在你的情况下。

Using ThreeTen Backport:

使用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));

This parses your line with 2-digit year into

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

2017-01-02 05:59:59

For the line with 4-digit year for which “in my requirement, parse exception should be thrown”, we get

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

Exception in thread "main" java.time.format.DateTimeParseException: Text ' 09/06/2017 05:59:59 20170609IT36701706080107 42 103 Output USD ...' could not be parsed at index 9

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

It says index 9, that’s at the 17 in 2017, that is, exactly where the third digit of the year is when there were only supposed to be two digits.

它表示指数9,即2017年的17,也就是说,当年只有两位数时,正好是今年的第三位数。

A couple of points to be aware of:

有几点需要注意:

  • Use capital HH in the format pattern for hour of day (small hh is for hour with AM or PM, only useful with an AM/PM marler). Use lowercase for the year, either uu or yy (not uppercase YY, it’s for weekbased year, only useful with a week number). BTW, again SimpleDateFormat let you get away with these bugs and will sometimes give you incorrect results; the modern classes will object by throwing an exception.
  • 在格式模式中使用大写HH表示一天中的小时数(小hh表示上午或下午的小时,仅适用于AM / PM marler)。年份使用小写,uu或yy(不是大写的YY,它是基于周的年份,仅对周数有用)。顺便说一句,SimpleDateFormat再次让你摆脱这些错误,有时会给你不正确的结果;现代类将通过抛出异常来反对。

  • My code will parse into a year from 2000 through 2099. Please check whether this is what you want. You may want to impose an additional restriction, for example, that the date-time should be in the past and not more than 5 years ago, for enhanced validation. You know better than I.
  • 我的代码将解析为2000年到2099年的一年。请检查这是否是你想要的。您可能希望施加额外的限制,例如,日期时间应该是过去且不超过5年,以进行增强验证。你知道的比我好。

To convert into your target format:

要转换为目标格式:

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

With the former of your lines the result is

使用前一行的结果是

2017-01-02 05:59:59

#2


0  

You can use regex to check if year contains 4 digits and if so throw new ParseException. The program is:

您可以使用正则表达式来检查年份是否包含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 {

        }

    }

#3


0  

Regex to match any of these date formats

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

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
}

#1


2  

Don't have option to use java 8 or later so cant use java.time

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

The Java 8 date and time classes have been backported to Java 6 and 7, so yes, you can use them in your Java 7. Get ThreeTen Backport. This is also the futureproof investment: if and when eventually you upgrade to Java 8 or 9, you will only have to modify your import declarations and your code will work with the java.time classes.

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

So I recommend you throw the outdated classes SimpleDateFormat and Date over the shoulder. It’s very typical for SimpleDateFormat to give you a result (very often an incorrect one) in a situation where you would want an exception. As you noted, sometimes org_format.setLenient(false); helps, but not in your case.

所以我建议你抛弃过时的类SimpleDateFormat和Date。在您想要异常的情况下,SimpleDateFormat非常典型地为您提供结果(通常是不正确的结果)。如你所述,有时org_format.setLenient(false);有帮助,但不是在你的情况下。

Using ThreeTen Backport:

使用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));

This parses your line with 2-digit year into

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

2017-01-02 05:59:59

For the line with 4-digit year for which “in my requirement, parse exception should be thrown”, we get

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

Exception in thread "main" java.time.format.DateTimeParseException: Text ' 09/06/2017 05:59:59 20170609IT36701706080107 42 103 Output USD ...' could not be parsed at index 9

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

It says index 9, that’s at the 17 in 2017, that is, exactly where the third digit of the year is when there were only supposed to be two digits.

它表示指数9,即2017年的17,也就是说,当年只有两位数时,正好是今年的第三位数。

A couple of points to be aware of:

有几点需要注意:

  • Use capital HH in the format pattern for hour of day (small hh is for hour with AM or PM, only useful with an AM/PM marler). Use lowercase for the year, either uu or yy (not uppercase YY, it’s for weekbased year, only useful with a week number). BTW, again SimpleDateFormat let you get away with these bugs and will sometimes give you incorrect results; the modern classes will object by throwing an exception.
  • 在格式模式中使用大写HH表示一天中的小时数(小hh表示上午或下午的小时,仅适用于AM / PM marler)。年份使用小写,uu或yy(不是大写的YY,它是基于周的年份,仅对周数有用)。顺便说一句,SimpleDateFormat再次让你摆脱这些错误,有时会给你不正确的结果;现代类将通过抛出异常来反对。

  • My code will parse into a year from 2000 through 2099. Please check whether this is what you want. You may want to impose an additional restriction, for example, that the date-time should be in the past and not more than 5 years ago, for enhanced validation. You know better than I.
  • 我的代码将解析为2000年到2099年的一年。请检查这是否是你想要的。您可能希望施加额外的限制,例如,日期时间应该是过去且不超过5年,以进行增强验证。你知道的比我好。

To convert into your target format:

要转换为目标格式:

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

With the former of your lines the result is

使用前一行的结果是

2017-01-02 05:59:59

#2


0  

You can use regex to check if year contains 4 digits and if so throw new ParseException. The program is:

您可以使用正则表达式来检查年份是否包含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 {

        }

    }

#3


0  

Regex to match any of these date formats

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

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
}