【问题标题】:SimpleDateFormat doesn't give me the pattern I needSimpleDateFormat 没有给我我需要的模式
【发布时间】:2016-06-26 16:30:04
【问题描述】:

我遇到了 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-object 打印特定日期 01-06-2016 的参数值。它显示了我 2016-06-01,即使我在上面的代码中的模式设置为 dd-MM-yyyy。

【问题讨论】:

  • 显示parameter的值
  • 这个值来自一个在 HTML 中具有日期类型的输入字段。这是一个可以选择日期的日历。
  • 它是如何获得价值的并不重要。重要的是它的样子。显示实际样本值。没有它,没有人可以帮助你。
  • 我会尝试用简单的 println 打印这个值并给你这个值。
  • 好吧,我尝试使用 PrintWriter-object 打印此值,当使用 dd-MM-yyyy 时,它给了我这个日期 2016-06-01。我尝试选择的日期是 01-06-2016。

标签: java html mysql database simpledateformat


【解决方案1】:

您将显示格式与内部表示混淆了。

数据库中的日期不以任何特定的显示格式表示,例如YYYY-MM-DD。数据库日期通常以数字形式存储,表示从某个固定起点开始的特定秒数和毫秒数(或纳秒数)。

当您查询数据库并以字符串形式请求日期/时间时,会动态应用显示格式,但如果您以 Date 对象的形式请求它,则会得到内部表示,封装在 java.sql.Date 中.

由您的 Java 代码根据需要格式化日期。

在您的特定示例中(根据您的评论),您的输入法返回的字符串是2016-06-01,因此您需要使用模式yyyy-MM-dd 对其进行解析。这会将外部表示正确地转换为有效的Date 对象。

但是我应该如何专门将这种表示更改为 dd-MM-yyyy

一旦您将其设置为Date,您就可以立即转身将Date 转换回具有不同SimpleDateFormat 规范的String

【讨论】:

  • 啊,我明白了,我想我理解你了。但是你有什么建议?我是否应该将我的值保存到一个字符串中并将这个字符串传递到我的数据库中,即使......它将保存在我的数据库中的列的类型为“日期”?
  • 不,您想将其存储为Date。正如我在上面评论的那样,在您向我们展示输入的示例之前,我们无法提供完整的答案。
  • 但是我应该如何专门将此表示更改为 dd-MM-yyyy。现在我很清楚输入字段给了我一个格式为 yyyy-MM-dd 的字符串,但是我怎样才能将其更改为我想要的呢?我尝试将上面代码中的模式更改为 dd-MM-yyyy,但这并没有像我已经说过的那样工作。对不起,如果我没有完全理解你。我对此有点陌生。
  • 您能给我一个代码示例,以便我更好地关注您吗?
【解决方案2】:

日期时间!= 字符串

正如correct Answer by Garrison 中所述,您必须了解,数据库内部或 Java 等语言中的日期值与为表示或传达该值而生成的字符串不同。

内部跟踪日期的方式因数据库和语言而异,实际上并不相关。重要的是提供的接口,您可以通过该接口获取或放置应用程序的值。 单独的问题是如何将这些值表示为字符串以呈现给您的用户。

数据库(内部)↔ 驱动程序 (JDBC) ↔ 应用程序 (java.time) ↔ 演示文稿(字符串)

java.time

此外,问题和其他答案正在使用旧的过时类,即与最早版本的 Java 捆绑在一起的日期时间类。这些类已被 Java 8 及更高版本中内置的 java.time 类所取代。见Oracle Tutorial。大部分功能已在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。

LocalDate

在 java.time 类中,LocalDate 表示没有时间和时区的仅日期值。旧的java.util.Date 类,尽管它的名字很不幸,但它同时跟踪日期一天中的时间。旧的 java.sql.Date 假装 表示仅日期,但实际上,在一个不幸的设计决策中,它从 java.util.Date 扩展,因此它继承了日期和时间,但是你在类文档中被指示假装它不是子类。 (是的,这是一个令人不快的混乱)

使用 LocalDate 等 java.time 类执行所有业务逻辑。

字符串和 ISO 8601

对于字符串,使用标准的ISO 8601 格式。对于仅序列化日期值,这意味着 YYYY-MM-DD。 java.time 类在解析/生成表示日期时间值的字符串时默认使用 ISO 8601 格式。

LocalDate localDate = LocalDate.parse( "2016-06-01" );

但尽量坚持对象。仅在必要时序列化为字符串。

数据库

从数据库获取数据时不需要字符串。 JDBC driver 的工作是弄清楚如何将 Java 对象移入/移出数据库列的数据类型。

使用符合JDBC 4.2 的驱动程序,您应该能够在PreparedStatement 上使用getObjectsetObject 方法直接处理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 );

您将需要使用格式化程序生成一个字符串以呈现给用户,并解析用户的输入。您或您的用户可能希望将数据输入作为三个单独的字段:年、月和日。

LocalDate localDate = LocalDate.of( 2016 , 6 , 1 );

【讨论】:

  • 谢谢,这真的很有帮助!
【解决方案3】:

如果您只想将您的日期格式化为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);
}

【讨论】:

  • 如果您尝试使用特定的字符串日期,这可能会起作用。但是我正在尝试为人们从该 html-calandre 中选择的所有日期执行此操作。我试过这个,它对我不起作用。它给了我 2016-06-01
【解决方案4】:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

java.sql.Date someDate;

Date anotherDate = format.parse(/*needVariables*/.getOutDate());

someDate = new java.sql.Date(anotherDate.getTime());

为我工作

【讨论】:

    猜你喜欢
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    相关资源
    最近更新 更多