如何在yyyy-mm-dd中正确格式化日期?

时间:2019-03-26 03:27:19

标签: java date java-7

我的MYSQL日期类型表中有一列,插入25-March-2019 hh:mm:ss的日期格式会返回错误,告诉我错误的数据值。

所以我的代码是这样写的:

 String startdt=request.getParameter("startdate");
    String enddate=request.getParameter("enddate");
    SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
    Date Startdate=dateFormat.parse(startdt);
    Date Enddate=dateFormat.parse(enddate);

我正在将StartdateEnddate传递给插入到我的表列中的函数。

有没有一种方法可以让上面的Startdate和Enddate只返回yyyy-mm-dd而没有时间,这样我就可以没有错误地插入数据库了?

2 个答案:

答案 0 :(得分:3)

tl; dr

myPreparedStatement
.setObject(
    LocalDate.parse( "2019-01-23" ) 
) ;

DATE在MySQL中是仅日期

MySQL中的DATE类型是仅日期的值,没有日期和时区。

摘录自MySQL 8.0 documentation

  

DATE类型用于具有日期部分但没有时间部分的值。 MySQL检索并以'YYYY-MM-DD'格式显示DATE值。支持的范围是“ 1000-01-01”到“ 9999-12-31”。

在Java中将仅日期类型用于来自数据库中仅日期类型的数据。您要使用的java.util.Date不是日期,它是UTC中的一个时刻,该日期中的时间与UTC的偏移量均为零,并且都已跟踪从1970年1月1日开始,以毫秒为单位。该类的错误命名只是那些程序员做出的许多糟糕的设计选择中的第一个。转到 java.time 类。 停止使用Date

MM =月号,而不是姓名

您的格式"yyyy-MM-dd"是数字月份,而不是示例值25-March-2019中显示的月份名称字符串。

避免使用旧的日期时间类

SimpleDateFormatDate类非常糟糕,糟糕的设计糟粕。几年前,通过在 java.time 类中实现的JSR 310取代了它们。

智能对象,而不是哑字符串

尽可能与数据库交换对象,而不是文本。

从JDBC 4.2开始,我们可以直接与数据库交换 java.time 对象。对于像SQL标准的DATE类型那样的仅日期值,请使用java.time.LocalDate类。

显然,您输入日期值的文本是YYYY-MM-DD,它是标准ISO 8601格式。默认情况下, java.time 类使用ISO 8601格式。因此,无需指定格式设置模式。

LocalDate localDate = LocalDate.parse( "2019-01-23" ) ;
myPreparedStatement.setObject( … , localDate ) ;

检索。

LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;
  

localDate.toString():2019-01-23

如果要生成一个字符串,以不同的文本格式表示该LocalDate对象的值,请使用DateTimeFormatter类。搜索堆栈溢出以获取更多信息,因为它与您的问题的其余部分一样,已经在堆栈溢出中涉及了很多次。发布前搜索堆栈溢出。

提示:通常最好在您的PreparedStatement工作中使用JDBC。一个主要好处是阻止SQL Injection安全攻击。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:2)

Java 7和ThreeTen Backport

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("d-MMMM-uuuu HH:mm:ss", Locale.ENGLISH);
    String dateFromHtmlForm = "25-March-2019 22:43:55";
    LocalDateTime dateTime = LocalDateTime.parse(dateFromHtmlForm, formatter);
    // We are discarding the time of day and only saving the date
    java.sql.Date dateToSave = DateTimeUtils.toSqlDate(dateTime.toLocalDate());

    String insertSql = "insert into your_table (your_date_column) values (?);";
    try (PreparedStatement insertStatement
            = yourDatabaseConnection.prepareStatement(insertSql)) {
        insertStatement.setDate(1, dateToSave);
        int rowsInserted = insertStatement.executeUpdate();
    }

如前所述,将日期对象传递给MySQL,而不是字符串。在Java 8和更高版本中,这些对象将是LocalDate对象,但是在Java 7中,我们将需要处理设计较差的java.sql.Date类。它仍然比字符串更好。并且LocalDate的转换非常简单。

在Java 7上,我们可以通过backport ThreeTen Backport(JSR-310的ThreeTen)使用java.time。我的进口是:

import org.threeten.bp.DateTimeUtils;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.format.DateTimeFormatter;

我们为什么要为此使用外部库?当然有优缺点。优点包括:

  • 与老式DateSimpleDateFormat相比,java.time更好用,并且代码更清晰。
  • 这是面向未来的:一旦您使用Java 8或更高版本,只需更改导入语句(并丢弃库并重新测试)即可。

链接