简体   繁体   中英

How to properly format Date in yyyy-mm-dd?

I have a column in my table of Date type in MYSQL and inserting the date format of 25-March-2019 hh:mm:ss returns an error telling me incorrect data value.

So I have my code written like this:

 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);

And I am passing Startdate and Enddate to a function that inserts into my table column.

Is there a way I can have Startdate and Enddate above just return in yyyy-mm-dd without the time so I can insert to my db without error?

tl;dr

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

DATE in MySQL is date-only

The DATE type in MySQL is a date-only value, without time-of-day and without time zone.

Excerpting from MySQL 8.0 documentation :

The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.

Use a date-only type in Java for data coming from a date-only type in your database. The java.util.Date class you are trying to use is not a date, it is a moment in UTC, a date with time-of-day and offset-from-UTC of zero, all tracked as a count of milliseconds from the first moment of 1970 in UTC. The misnaming of that class is only the first of many poor design choices made by those programmers. Move on to java.time classes instead. Stop using Date .

MM = month number, not name

Your format of "yyyy-MM-dd" is for a numeric month, not the string of month name shown in your example value of 25-March-2019 .

Avoid legacy date-time classes

The SimpleDateFormat and Date classes are terrible, a wretched mess of bad design. They were supplanted years ago with the adoption of JSR 310, implemented in the java.time classes.

Smart objects, not dumb strings

Exchange objects with your database where possible, not text.

As of JDBC 4.2, we can directly exchanged java.time objects with the database. For a date-only value, as with SQL-standard DATE type, use the java.time.LocalDate class.

Apparently, your text inputs for date values is YYYY-MM-DD which is standard ISO 8601 format. The java.time classes use ISO 8601 formats by default. So no need to specify a formatting pattern.

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

Retrieval.

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

localDate.toString(): 2019-01-23

If you want to produce a string representing the value of that LocalDate object in a different textual format, use the DateTimeFormatter class. Search Stack Overflow for more info as it, like the rest of your Question, has been covered many times already on Stack Overflow. Do search Stack Overflow before posting.

Tip: Generally best to use a PreparedStatement in your JDBC work. One major benefit is thwarting SQL Injection security attacks.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .

To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification is JSR 310 .

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more .

Java 7 and 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();
    }

As has already been said, pass date objects to MySQL, not strings. In Java 8 and later these would have been LocalDate objects, but in Java 7 we will need to make do with the poorly designed java.sql.Date class. It's still better than strings. And the conversion from LocalDate is straightforward.

On Java 7 we can use java.time through the backport, ThreeTen Backport (ThreeTen for JSR-310). My imports are:

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

Why would we want to use an external library for this? There are pros and cons, of course. Advantages include:

  • java.time is so much nicer to work with than the old-fashoined Date and SimpleDateFormat and gives clearer code.
  • It's future-proof: once you move to Java 8 or later, all you need to do is change your import statements (and discard the library and retest).

Links

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM