我遇到SimpleDateFormat问题。我的HTML页面中的输入字段为type = date。我想将这些值保存到我的数据库中,它们应该保存为日期。我已经想出了如何做到这一点,它的工作原理。我唯一的探测器就是日期在数据库中的表示方式。
我希望它们被表示为dd-MM-yyyy。假设我想将01-06-2016显示在我的数据库中。当我使用代码执行此操作时..它给了我0006-12-07。奇怪的是......当我将我的模式改为yyyy-MM-dd时......它确实给了我模式所说的内容:2016-06-01。但它反过来不起作用。
String parameter = request.getParameter("instroomdatum");
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
try {
Date parsed = sdf.parse(parameter);
java.sql.Date sql = new java.sql.Date(parsed.getTime());
student.setInstroomdatum(sql);
} catch (ParseException ex) {
Logger.getLogger(StudentController.class.getName()).log(Level.SEVERE, null, ex);
}
有人可以解释一下发生了什么以及如何解决这个问题?真的很烦人。
编辑:我尝试使用简单的PrintWriter-object打印参数值,以用于特定日期01-06-2016。它向我显示2016-06-01,即使我在上面的代码中的模式设置为dd-MM-yyyy。
答案 0 :(得分:2)
您将显示格式与内部表示混淆。
数据库中的日期不以任何特定显示格式 代表,例如YYYY-MM-DD
。数据库日期通常以数字形式存储,表示从某个固定起点开始的特定秒数和毫秒数(或纳秒数)。
当您查询数据库并以字符串形式请求日期/时间时,将动态应用显示格式,但如果您将其作为Date
对象请求,则会获得内部表示形式,封装在{ {1}}。
由Java代码根据需要格式化日期。
在您的特定示例中(根据您的注释),输入法返回的字符串为java.sql.Date
,因此您需要使用模式2016-06-01
对其进行解析。这将正确地将外部表示转换为有效的yyyy-MM-dd
对象。
但我应该如何具体地将此表示更改为dd-MM-yyyy
将其作为Date
后,您可以立即转身并将Date
转换回Date
,并使用不同的String
规范。
答案 1 :(得分:0)
如果您只想将日期格式化为01-06-2016
格式。试试这个
String parameter = "0006-12-07";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date parsed = sdf.parse(parameter);
sdf = new SimpleDateFormat("dd-MM-yyyy");
System.out.println(sdf.format(parsed)); //Prints out your desired format 07-12-0006
java.sql.Date sql = new java.sql.Date(parsed.getTime());
student.setInstroomdatum(sql);
} catch (ParseException ex) {
Logger.getLogger(StudentController.class.getName()).log(Level.SEVERE,null, ex);
}
答案 2 :(得分:0)
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
java.sql.Date someDate;
Date anotherDate = format.parse(/*needVariables*/.getOutDate());
someDate = new java.sql.Date(anotherDate.getTime());
为我工作
答案 3 :(得分:0)
如correct Answer by Garrison中所述,您必须了解数据库内部或Java等语言中的日期值是不同的,而不是为表示或传递该值而生成的字符串。
如何在内部跟踪日期因数据库和语言而异,并且确实无关紧要。重要的是提供的界面,您可以通过该界面获取或放置您的应用程序的值。 单独的问题是如何将这些值表示为字符串以便呈现给您的用户。
此外,问题和其他答案正在使用旧的过时类,即与最早版本的Java捆绑在一起的日期时间类。这些类已被Java 8及更高版本中内置的java.time类所取代。见Oracle Tutorial。许多功能已经被后端移植到Java 6& ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。
LocalDate
在java.time类中,LocalDate
表示没有时间且没有时区的仅限日期的值。旧的java.util.Date
类,尽管名称不幸,但它跟踪日期和的时间。旧的java.sql.Date
假装代表仅限日期,但事实上,在一个不幸的设计决策中,从java.util.Date
延伸,因此它继承了日期和时间一天,但是你在类doc中被指示假装它不是子类。 (是的,这是一个令人不快的混乱)
使用java.time类(例如LocalDate
。
对于字符串,请使用标准ISO 8601格式。对于序列化仅日期值,这意味着YYYY-MM-DD。在解析/生成表示日期时间值的字符串时,java.time类默认使用ISO 8601格式。
LocalDate localDate = LocalDate.parse( "2016-06-01" );
但试着坚持使用物体。只在必要时序列化为字符串。
从数据库获取数据时不需要字符串。 JDBC driver的工作是弄清楚如何将Java对象移入/移出数据库列的数据类型。
使用符合JDBC 4.2的驱动程序,您应该能够使用PreparedStatement
上的getObject
和setObject
方法直接处理java.time类型。
myPreparedStatement.setObject( 1 , localDate );
如果您的驱动程序不支持,则必须回退到java.sql.Date类。寻找添加到旧类中的新方法来与java.time类型进行来回。
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
另一个方向。
LocalDate localDate = sqlDate.toLocalDate();
应用格式以根据需要生成字符串以呈现给用户。使用DateTimeFormatter
课程。您可以定义自己的格式模式。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd-MM-yyyy" );
String output = localDate.format( formatter ); // 01-06-2016
更好的是,让java.time本地化为用户期望/期望Locale
的人类语言和文化规范。
Locale locale = Locale.CANADA_FRENCH;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT , locale );
String output = localDate.format( formatter );
您需要使用格式化程序生成一个String,以便向用户显示,并解析用户输入的内容。您或您的用户可能希望将数据输入作为三个单独的字段:年,月和日。
LocalDate localDate = LocalDate.of( 2016 , 6 , 1 );