简体   繁体   English

Java-SimpleDateFormat意外的解析行为

[英]Java - SimpleDateFormat unexpected parsing behaviour

I'm reading information from a file (.csv) that will be inserted to a database after validation and approval from the end user. 我正在从文件(.csv)中读取信息,该文件将在最终用户验证和批准后插入数据库。 The text file is read, validated and its information loaded to a List containing forms which are used to check if the data already exist in database. 读取,验证文本文件并将其信息加载到包含表单的列表中,这些表单用于检查数据库中是否已存在数据。

The problem arises when parsing the String to Date. 将字符串解析为Date时出现问题。 The SimpleDateFormat.parse() method returns an unexpected date format even when the pattern for SimpleDateFormat is "yyyy-MM-dd". 即使SimpleDateFormat的模式为“ yyyy-MM-dd”,SimpleDateFormat.parse()方法也会返回意外的日期格式。

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);

Parsing the loaded values to the travel object: 将加载的值解析为旅行对象:

travel.setDate( dateFormat.parse( form.getTravelDate() ));

In debugger the form shows the date as: 在调试器中,表单将日期显示为:

"2012-12-12"

It is read as intended. 按预期阅读。 However when parsed becomes: 但是,解析后变成:

Wed Dec 12 00:00:00 CST 2012

I've spent the whole day trying to solve this but I'm out of ideas at this point. 我花了整整一天的时间来解决这个问题,但目前我还没有想法。 Afaik the pattern is alright and I've tried adding a locale to no avail. Afaik的模式还可以,我尝试添加区域设置无济于事。

Edit: the problem is when I need to insert the values to the database using Hibernate. 编辑:问题是当我需要使用Hibernate将值插入数据库时​​。 The not desired format also ends up showing in the Database. 不需要的格式也最终显示在数据库中。

The data is show in a .jsp page using 数据显示在.jsp页面中,使用

 HttpServletRequest("table",travelList);

The date format I don't need shows here, when in the past this issue never happened. 我不需要的日期格式在这里显示,过去从未发生过此问题。 At last the information is sent to the database where the problem persists. 最后,信息被发送到问题仍然存在的数据库。

No, it "becomes" a java.util.Date value. 不,它“成为” java.util.Date值。 If you're then converting it back to a string by calling Date.toString() , you should consult the Date.toString() documentation for what to expect. 如果随后通过调用Date.toString()将其转换字符串,则应查阅Date.toString()文档以了解期望的内容。

The value stored in the Date is just a point in time - the number of milliseconds since the Unix epoch. Date存储的值只是一个时间点-自Unix时代以来的毫秒数。 There's no format in there, no time zone etc. It also doesn't know that it was only a date value rather than a date and time (the naming of Date is one of the many unfortunate aspects of the API). 那里没有格式,没有时区等。它也不知道这只是一个日期值,而不是日期和时间( Date的命名是API的许多不幸方面之一)。

It's crucial that you mentally separate "the result of the parse operation" from "the string value that is used to represent that result if I call toString" ". 至关重要的是,您必须在头脑中将“解析操作的结果”与“如果我调用toString"用来表示该结果的字符串值”分开。

I'd also advise you to set the time zone on your SimpleDateFormat to UTC when parsing a date - that way you know that you can't possibly have any ambiguous or skipped times leading to hard-to-predict behaviour. 我还建议您在解析日期时,将SimpleDateFormat上的时区设置为SimpleDateFormat这样,您就知道您不可能有任何模棱两可或跳过的时间,从而导致难以预测的行为。 (Of course, you then need to know that you'll have parsed the date to "the start of the UTC date" and handle it appropriately elsewhere.) (当然,然后,您需要知道将日期解析为“ UTC日期的开始”,并在其他位置进行适当处理。)

You need to use the formatter when printing the Date as well. 在打印Date ,也需要使用格式化程序。

dateFormat.format( travel.getDate() );

When your parse the String using a DateFormat , you get a complete Date object with the time units missing in the string initialized to zero. 当使用DateFormat解析String ,您将获得一个完整的Date对象,该字符串中缺少的时间单位被初始化为零。 In your example, that's hours, minutes and seconds. 在您的示例中,是小时,分钟和秒。

By default, if you do not use a formatter, Date 's default string representation (provided by its toString() method) gets printed. 默认情况下,如果不使用格式化程序,则将打印Date的默认字符串表示形式(由其toString()方法提供)。

Parsing doesn't mean it format, it simply parse it as text to a java.util.Date object. 解析并不意味着其格式,它只是将其解析为文本到java.util.Date对象。 See parse method in documentation . 请参阅文档中的parse方法

You need to use the format method. 您需要使用format方法。

dateFormat.format(travel.getDate())

See documentation for more details. 有关更多详细信息,请参见文档

if form.getTravelDate() is returning String then First Parse the Date from String 如果form.getTravelDate()返回String,则首先从String Parse日期

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
Date parsedDate=dateFormat.parse(form.getTravelDate()); 
// Here parsedDate is in form Wed Dec 12 00:00:00 CST 2012 

Now Format the Date using the Same SImpleDateFormat to get the desired output 现在使用相同的SImpleDateFormat格式化日期以获取所需的输出

System.out.println(dateFormat.format(parsedDate));

Your Desired Output 您想要的输出

2012-12-12

Update 更新

Assuming data Type of Columns in which we insert this data in Database is of Date Type not varchar then use the below statement 假设要在数据库中插入此数据的列的数据类型是Date类型,而不是varchar则使用以下语句

travel.setDate(dateFormat.format(parsedDate));

As I understand parse method returns Date . 据我了解, parse方法返回Date Below is the parse method syntax. 下面是解析方法的语法。

public Date parse(String source)
           throws ParseException

So, you need to parse the string date and store into a Date variable. 因此,您需要解析字符串date并将其存储到Date变量中。 Then format the Date variable using SimpleDateFormat . 然后使用SimpleDateFormat格式化Date变量。

//getTravelDate is "2012-12-12"

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
Date dtObj=new Date(); 
dtObj=dateFormat.parse(form.getTravelDate());   //Store in date variable    
System.out.println(dateFormat.format(dtObj)); // Now format the date object

The final output will be 2012-12-12 . 最终输出将是2012-12-12 Hope it will help you. 希望对您有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM