SimpleDateFormat 没有提供我需要的模式
SimpleDateFormat doesn't give me the pattern I need
我在使用 SimpleDateFormat 时遇到问题。我的 HTML 页面中有输入字段,类型为日期。我想将这些值保存到我的数据库中,在那里它们应该被保存为日期。我已经想出如何做到这一点并且它有效。我遇到的唯一问题是日期在数据库中的表示方式。
我希望将它们表示为 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 对象打印特定日期 01-06-2016 的参数值。它显示 2016-06-01,即使我在上面代码中的模式设置为 dd-MM-yyyy。
您混淆了显示格式与内部表示。
数据库中的日期不会以任何特定显示格式表示,例如YYYY-MM-DD
。数据库日期通常以数字形式存储,表示从某个固定起点算起的一定秒数和毫秒数(或纳秒数)。
当您查询数据库并以字符串形式请求 date/time 时动态应用显示格式,但如果您以 Date
对象形式请求它,您将获得内部表示,封装在java.sql.Date
中。
由您的 Java 代码根据需要格式化日期。
在您的特定示例中(根据您的评论),您的输入法返回的字符串是 2016-06-01
,因此您需要使用模式 yyyy-MM-dd
来解析它。这会将外部表示正确地转换为有效的 Date
对象。
But how should i specifically change this representation to dd-MM-yyyy
一旦您将其设为 Date
,您可以立即将 Date
转换回具有不同 SimpleDateFormat
规格的 String
。
如果您只想将日期格式化为 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);
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
java.sql.Date someDate;
Date anotherDate = format.parse(/*needVariables*/.getOutDate());
someDate = new java.sql.Date(anotherDate.getTime());
为我工作
日期时间 != 字符串
如 中所述,您必须了解数据库内部或 Java 等语言中的日期值是不同的,与生成的用于表示或传达的字符串不同价值。
内部跟踪日期的方式因数据库和语言而异,实际上是无关紧要的。重要的是提供的接口,您可以通过该接口获取或放置应用程序的值。 另一个 问题是如何将这些值表示为字符串以呈现给您的用户。
Database (internal) ↔ Driver (JDBC) ↔ App (java.time) ↔ Presentation (String)
java.time
此外,问题和其他答案使用的是过时的旧 classes,日期时间 classes 与最早版本的 Java 捆绑在一起。 classes 已被 java.time classes built into Java 8 and later. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
取代
LocalDate
java.time class 中的 LocalDate
表示没有时间和时区的仅日期值。旧的 java.util.Date
class,尽管它的名字很不幸,但它同时跟踪日期 和 一天中的时间。旧的 java.sql.Date
假装 表示仅日期,但实际上,在一个不幸的设计决定中,它从 java.util.Date
扩展,因此它继承了日期和时间-of-day,但 class 文档中指示您假装它不是子 class。 (是的,那是一团糟)
使用 java.time class 执行所有业务逻辑,例如 LocalDate
。
字符串和 ISO 8601
至于字符串,请使用标准 ISO 8601 格式。对于序列化仅限日期的值,这意味着 YYYY-MM-DD。当 parsing/generating 表示日期时间值的字符串时,java.time classes 默认使用 ISO 8601 格式。
LocalDate localDate = LocalDate.parse( "2016-06-01" );
但尽量坚持使用对象。仅在必须时序列化为字符串。
数据库
获取数据时不需要字符串 to/from 数据库。 JDBC driver 的工作是弄清楚如何移动 Java 对象 to/from 数据库列的数据类型。
使用符合 JDBC 4.2, you should be able to use the getObject
and setObject
methods on a PreparedStatement
的驱动程序直接处理 java.time 类型。
myPreparedStatement.setObject( 1 , localDate );
如果您的驱动程序不支持,您必须退回到 java.sql.Date class。寻找添加到旧 classes 的新方法,以便与 java.time 类型来回切换。
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
另一个方向。
LocalDate localDate = sqlDate.toLocalDate();
生成字符串
根据需要应用一种格式来生成字符串,以便向用户展示。使用DateTimeFormatter
class。您可以定义自己的格式模式。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd-MM-yyyy" );
String output = localDate.format( formatter ); // 01-06-2016
更好的是,让 java.time 本地化到用户 desired/expected Locale
的人类语言和文化规范。
Locale locale = Locale.CANADA_FRENCH;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT , locale );
String output = localDate.format( formatter );
您将需要使用格式化程序生成一个字符串以呈现给用户,并解析用户的输入。您或您的用户可能希望将数据输入作为三个单独的字段:年、月和月中的某天。
LocalDate localDate = LocalDate.of( 2016 , 6 , 1 );
我在使用 SimpleDateFormat 时遇到问题。我的 HTML 页面中有输入字段,类型为日期。我想将这些值保存到我的数据库中,在那里它们应该被保存为日期。我已经想出如何做到这一点并且它有效。我遇到的唯一问题是日期在数据库中的表示方式。
我希望将它们表示为 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 对象打印特定日期 01-06-2016 的参数值。它显示 2016-06-01,即使我在上面代码中的模式设置为 dd-MM-yyyy。
您混淆了显示格式与内部表示。
数据库中的日期不会以任何特定显示格式表示,例如YYYY-MM-DD
。数据库日期通常以数字形式存储,表示从某个固定起点算起的一定秒数和毫秒数(或纳秒数)。
当您查询数据库并以字符串形式请求 date/time 时动态应用显示格式,但如果您以 Date
对象形式请求它,您将获得内部表示,封装在java.sql.Date
中。
由您的 Java 代码根据需要格式化日期。
在您的特定示例中(根据您的评论),您的输入法返回的字符串是 2016-06-01
,因此您需要使用模式 yyyy-MM-dd
来解析它。这会将外部表示正确地转换为有效的 Date
对象。
But how should i specifically change this representation to dd-MM-yyyy
一旦您将其设为 Date
,您可以立即将 Date
转换回具有不同 SimpleDateFormat
规格的 String
。
如果您只想将日期格式化为 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);
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
java.sql.Date someDate;
Date anotherDate = format.parse(/*needVariables*/.getOutDate());
someDate = new java.sql.Date(anotherDate.getTime());
为我工作
日期时间 != 字符串
如
内部跟踪日期的方式因数据库和语言而异,实际上是无关紧要的。重要的是提供的接口,您可以通过该接口获取或放置应用程序的值。 另一个 问题是如何将这些值表示为字符串以呈现给您的用户。
Database (internal) ↔ Driver (JDBC) ↔ App (java.time) ↔ Presentation (String)
java.time
此外,问题和其他答案使用的是过时的旧 classes,日期时间 classes 与最早版本的 Java 捆绑在一起。 classes 已被 java.time classes built into Java 8 and later. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
取代LocalDate
java.time class 中的 LocalDate
表示没有时间和时区的仅日期值。旧的 java.util.Date
class,尽管它的名字很不幸,但它同时跟踪日期 和 一天中的时间。旧的 java.sql.Date
假装 表示仅日期,但实际上,在一个不幸的设计决定中,它从 java.util.Date
扩展,因此它继承了日期和时间-of-day,但 class 文档中指示您假装它不是子 class。 (是的,那是一团糟)
使用 java.time class 执行所有业务逻辑,例如 LocalDate
。
字符串和 ISO 8601
至于字符串,请使用标准 ISO 8601 格式。对于序列化仅限日期的值,这意味着 YYYY-MM-DD。当 parsing/generating 表示日期时间值的字符串时,java.time classes 默认使用 ISO 8601 格式。
LocalDate localDate = LocalDate.parse( "2016-06-01" );
但尽量坚持使用对象。仅在必须时序列化为字符串。
数据库
获取数据时不需要字符串 to/from 数据库。 JDBC driver 的工作是弄清楚如何移动 Java 对象 to/from 数据库列的数据类型。
使用符合 JDBC 4.2, you should be able to use the getObject
and setObject
methods on a PreparedStatement
的驱动程序直接处理 java.time 类型。
myPreparedStatement.setObject( 1 , localDate );
如果您的驱动程序不支持,您必须退回到 java.sql.Date class。寻找添加到旧 classes 的新方法,以便与 java.time 类型来回切换。
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
另一个方向。
LocalDate localDate = sqlDate.toLocalDate();
生成字符串
根据需要应用一种格式来生成字符串,以便向用户展示。使用DateTimeFormatter
class。您可以定义自己的格式模式。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd-MM-yyyy" );
String output = localDate.format( formatter ); // 01-06-2016
更好的是,让 java.time 本地化到用户 desired/expected Locale
的人类语言和文化规范。
Locale locale = Locale.CANADA_FRENCH;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT , locale );
String output = localDate.format( formatter );
您将需要使用格式化程序生成一个字符串以呈现给用户,并解析用户的输入。您或您的用户可能希望将数据输入作为三个单独的字段:年、月和月中的某天。
LocalDate localDate = LocalDate.of( 2016 , 6 , 1 );