Java-SimpleDataFormat意外的解析行为

Java-SimpleDataFormat意外的解析行为,java,spring,date,Java,Spring,Date,我正在从文件(.csv)中读取信息,该文件将在最终用户验证和批准后插入数据库。读取、验证文本文件,并将其信息加载到包含表单的列表中,这些表单用于检查数据库中是否已经存在数据 解析到目前为止的字符串时会出现问题。即使SimpleDataFormat的模式为“yyyy-MM-dd”,该方法也会返回意外的日期格式 将加载的值解析为travel对象: travel.setDate( dateFormat.parse( form.getTravelDate() )); 在调试器中,该表单将日期显示为:

我正在从文件(.csv)中读取信息,该文件将在最终用户验证和批准后插入数据库。读取、验证文本文件,并将其信息加载到包含表单的列表中,这些表单用于检查数据库中是否已经存在数据

解析到目前为止的字符串时会出现问题。即使SimpleDataFormat的模式为“yyyy-MM-dd”,该方法也会返回意外的日期格式

将加载的值解析为travel对象:

travel.setDate( dateFormat.parse( form.getTravelDate() ));
在调试器中,该表单将日期显示为:

"2012-12-12"
按原意阅读。但是,当解析为:

Wed Dec 12 00:00:00 CST 2012
我花了一整天的时间试图解决这个问题,但现在我已经没有主意了。好了,模式还可以,我试着添加一个区域设置,但没有效果

编辑:问题是当我需要使用Hibernate将值插入数据库时。不需要的格式最终也会显示在数据库中

数据显示在.jsp页面中,使用

 HttpServletRequest("table",travelList);
我不需要的日期格式显示在这里,而在过去这个问题从未发生过。最后,信息被发送到问题仍然存在的数据库

否,它“成为”一个
java.util.Date
值。如果随后通过调用
Date.toString()
将其转换回字符串,则应参考
Date.toString()
文档了解预期内容

存储在
Date
中的值只是一个时间点—自Unix纪元以来的毫秒数。这里没有格式,没有时区等。它也不知道它只是一个日期值,而不是一个日期和时间(日期的命名是API中许多不幸的方面之一)

至关重要的是,您必须在心里将“解析操作的结果”与“如果我调用
toString”
,则用于表示该结果的字符串值”分开


我还建议您在解析日期时将
SimpleDateFormat
上的时区设置为UTC,这样您就知道不可能有任何含糊不清或跳过的时间导致难以预测的行为。(当然,您还需要知道,您已经将日期解析为“UTC日期的开始”)“并在其他地方适当处理。)

打印日期时也需要使用格式化程序

dateFormat.format( travel.getDate() );
当您使用
日期格式
解析
字符串
时,您会得到一个完整的
日期
对象,其中字符串中缺少的时间单位初始化为零。在您的示例中,这是小时、分钟和秒


默认情况下,如果不使用格式化程序,
Date
的默认字符串表示形式(由其
toString()
方法提供)会被打印出来。

解析并不意味着格式化,它只是将其作为文本解析为
java.util.Date
对象。看

您需要使用
格式
方法

dateFormat.format(travel.getDate())

有关更多详细信息,请参阅。

如果
form.getTravelDate()
返回字符串,则首先
解析字符串中的日期

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 
现在使用相同的SimpleDataFormat格式化日期,以获得所需的输出

System.out.println(dateFormat.format(parsedDate));
您想要的输出

2012-12-12
更新

假设我们在数据库中插入此数据的列的数据类型为
Date
类型而不是
varchar
,则使用下面的语句

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

据我所知,
parse
方法返回
Date
。下面是解析方法语法

public Date parse(String source)
           throws ParseException
因此,您需要解析字符串date并将其存储到日期变量中。然后使用
SimpleDataFormat
格式化日期变量

//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

最终输出将为
2012-12-12
。希望它能帮助您。

解析(从字符串到日期)与格式(从日期到字符串)没有任何关系。我知道,如果需要显示值,情况会有所不同,问题是我不需要显示它。setAttribute(“table”,dateList)是我在插入之前做的最后一件事,它也会执行相同的问题。不管怎样,我会试着设置UTC,看看它会产生什么结果。@lhuezo:你说的“它也会产生同样的问题”是什么意思?您还没有描述实际问题是什么,我们也不知道这里有什么
request
。如果您对特定的字符串表示法感兴趣,则需要适当设置
日期
值的格式。当执行插入操作时,日期将以不需要的格式插入。关于这个请求,对不起。我的意思是HttpServletRequest.setAttribute()。我将检查日期表示,希望如此。@lhuezo:servlet与插入有什么关系?它被插入到什么中?该请求属性是如何使用的?您在这里遗漏了大量的上下文。我认为没有必要详细讨论这一部分,因为严格来说,这是一个发生在用于加载文件值的类上的问题。我的意思是,信息不再需要任何操作,解析后它只显示在表中,等待手动批准。但表中显示的格式不正确,在批准数据时也会对数据库执行此操作。这意味着我需要返回到字符串,然后返回到日期对象?@lhuezo否,您可以直接跳过解析步骤并直接格式化travel.getDate()问题是我不需要显示值,实际上,我需要将它以上述格式插入数据库。我觉得奇怪,在解析字符串之后,我必须将其设置回字符串。
//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