4

I am touching Java for the very first time here, so go easy on me. I am having to correct someone else's older code. This java program takes data from a MySQL table and prepares it for presentation on web pages. I found that their MySQL table for some reason used INT fields for all the dates. So, for instance, today's date is stored as the INT 3222017. I first had to add the proper DATE columns to the MySQL table. Next I re-did another Java script to pull the data from a larger table for the MySQL table that this script will be using.

Now I need to change the code that currently formats the INT fields into MM/dd/yyyy to instead take the DATE fields (stored as yyyy-MM-dd) and convert them to the same MM/dd/yyyy.

Here is a piece of the code that uses the function dateFormat on the INT fields -

String formattedDate = "";

            formattedDate = dateFormat(oneSpectro.getSpectroLastDate());
            result.setSpectroLastDate(formattedDate);

            formattedDate = dateFormat(oneSpectro.getSpectroOrigDate());
            result.setSpectroOrigDate(formattedDate);

            formattedDate = dateFormat(oneSpectro.getSpectroCalDate());
            result.setSpectroCalDate(formattedDate);
            }

        return result;
    }

And here is the dateFormat function -

public String dateFormat(int theDate){
        String      dateString = "";
        Integer     dateInt = 0;

        if (theDate < 10000000){
            dateInt = new Integer(theDate);
            dateString = dateInt.toString();
            // Add preceding 0 to make the date 8 digits in length.
            dateString  = "0" + dateString;

        }
        else {
            // Process an 8 digit date.
            dateInt = new Integer(theDate);
            dateString = dateInt.toString();
        }
        // Install date slashes in the date string.
        if (dateString.length() == 8){
            dateString = dateString.substring(0, 2) + "/" + dateString.substring(2, 4) + "/" 
                    + dateString.substring(4);
        }
        return dateString;
    }

How do I go about converting a DATE field (yyyy-MM-dd) to a formatted date of MM/dd/yyyy?

BigRedEO
  • 807
  • 4
  • 13
  • 33
  • 2
    What about 1112017? is that 1-11-2017 or 11-1-2017? – Gurwinder Singh Mar 22 '17 at 17:48
  • Good question! I hadn't even thought about that - but it might also be why I was asked to look at what was going on since some of the pages were displaying inaccurate data. – BigRedEO Mar 22 '17 at 17:52
  • 1
    If you have the database fixed with a proper `DATE` column, load it normally as a `java.sql.Date`, then format it with `SimpleDateFormat`. Also, some people shouldn't be allowed to touch databases. – Kayaman Mar 22 '17 at 17:53
  • @Kayaman - so skip the dateFormat function and just use SimpleDateFormat the formattedDate section in the first piece of code? – BigRedEO Mar 22 '17 at 17:55
  • 1
    Well, the `dateFormat()` exists only because someone had the genius idea of storing dates in such a moronic way. When you're reading normal dates, you've got all the formatting functionality included in Java. Also, the date isn't actually stored in `2010-01-01` format. It's *displayed* to you in that format. – Kayaman Mar 22 '17 at 17:56

3 Answers3

6

You can convert String to Date util:

 DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
 Date date = format.parse(your string);

And then convert the Date object to your String format:

 DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
 String result = df.format(date);
João Marcos
  • 3,872
  • 1
  • 19
  • 14
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), and `java.text.SimpleTextFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. – Basil Bourque Mar 23 '17 at 05:34
  • A slight variation on this is what ultimately worked for me. Thank you! – BigRedEO Mar 27 '17 at 19:45
3

tl;dr

LocalDate.parse(                               // Use modern java.time classes rather than troublesome legacy date-time classes
    String.format("%08d", 3222017) ,           // Let Java pad with leading zero.
    DateTimeFormatter.ofPattern( "MMdduuuu" )  // Parse string as a `LocalDate`.
)

2017-03-22

DATE column type

That is one ridiculously bad way to store a date value.

When storing date data, one should use a date datatype when defining the database column.

You should not be using integers nor strings for moving this data in and out of your database. Let your JDBC driver do its job, transmitting java.time.LocalDate objects to/from your database’s column defined as a date datatype. In MySQL that would be the DATE type.

If your JDBC driver complies with JDBC 4.2 or later, use the PreparedStatement::setObject and ResultSet::getObject methods to pass & get a java.time.LocalDate object. For older drivers, convert the java.time types to the legacy java.sql types such as java.sql.Date. Look for new methods added to the old classes for conversion.

java.sql.Date sqlDate = java.sql.Date.valueOf( myLocalDate );

Going the other direction.

LocalDate localDate = myJavaSqlDate.toLocalDate();

java.time

The other Answers use the troublesome old legacy date-time classes. Those are now legacy, supplanted by the java.time classes.

The LocalDate class represents a date-only value without time-of-day and without time zone.

The format YYYY-MM-DD for dates is defined in the ISO 8601 standard. The java.time classes use the standard formats by default. So no need to specify a formatting pattern.

LocalDate localDate = LocalDate.parse( "2017-03-22" );

To parse your funky pseudo-integer string, define a formatting pattern to match.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMdduuuu" );

To generate that string from the integer, you can shorten that existing code of yours by letting Java pad with leading zero.

String input = String.format("%08d", 3222017) ;

03222017

Parse that input using the DateTimeFormatter to produce a LocalDate object.

LocalDate localDate = LocalDate.parse( input , f );

localDate.toString(): 2017-03-22

See this code run live at IdeOne.com.


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.

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

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

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.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • I won't be parsing the INT fields. That is what the program is currently doing. I have added DATE columns matching the three INT columns currently used for the dates. Now I just need to know how to format the DATE columns as MM/dd/yyyy instead of as they are shown in MySQL as yyyy-MM-dd. So are you saying that until I can confirm whether JDBC complies with 4.2 or better, I should be able to use `java.sql.Date sqlDate = java.sql.Date.valueOf( myLocalDate );` to get the dates to show in my desired format? – BigRedEO Mar 23 '17 at 16:00
  • 1
    @BigRedEO For modern JDBC 4.2 drivers, you do not need `java.sql.Date` *at all*. **Use only java.time classes** whenever possible. The legacy date-time classes are a bloody mess, poorly designed, with awkward hacks. If your driver is not yet updated, fall back to java.sql types but immediately convert to java.time objects by calling new conversion methods added to the old classes. With a `java.time.LocalDate` in hand, generate a string in desired format. Reread my Answer; all this is covered. Search Stack Overflow for many more examples. – Basil Bourque Mar 23 '17 at 18:40
0
    try {
        String dateString = "2017-03-22";

        // convert string to date
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        Date date = f.parse(dateString);

        // change the date format
        SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
        String result = df.format(date);

    } catch(ParseException e) {
        throw new RuntimeException(e);
    }

Joao's solution works. A few gotchas:

  • In my compiler I couldn't convert DateFormat to SimpleDateFormat. I stuck with using the SimpleDateFormat object.
  • My compiler enforces a use of a try-catch block. A try catch block is needed in case it can't convert from String to SimpleDateFormat. If it can't parse, log an error with a ParseException.

I hope this helps.

uberdwang
  • 77
  • 1
  • 8