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