简体   繁体   中英

Date object formatting

I'm trying to format an input date in Java which looks like follows in the debugger.

result = {Date@13861} "2019-09-29"
 fastTime = 1569729600000
 cdate = {Gregorian$Date@13873} "2019-09-29T00:00:00.000-0400"

I need to convert it into: 2019-09-28 20:00:00.0 .

My code:

DateTimeFormatter dateTimeformatter_Test = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

LocalDate tempDate = LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern( "yyyy-MM-dd" , Locale.US ));

But the line below throws a runtime error saying: Unsupported field: HourOfDay

String result= tempDate.format(dateTimeformatter_Test);

What am I missing here please?

Thanks.

Your question is lacking time zone information, but here is one way to convert 2019-09-29 into 2019-09-28 20:00:00.0 :

System.out.println(
        LocalDate.parse("2019-09-29")
        .atStartOfDay(ZoneOffset.UTC)
        .withZoneSameInstant(ZoneId.of("America/New_York"))
        .format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S")));

Output

2019-09-28 20:00:00.0

Here is an entirely different way, showing the values you saw in the debugger:

TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));

java.sql.Date result = java.sql.Date.valueOf("2019-09-29");
System.out.println("result = " + result);

long fastTime = result.getTime();
System.out.println("fastTime = " + fastTime);

System.out.println("cdate = " + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(result));

ZonedDateTime zdt = Instant.ofEpochMilli(fastTime).atZone(ZoneId.of("America/Anchorage"));
System.out.println("zdt = " + zdt.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S")));

Output

result = 2019-09-29
fastTime = 1569729600000
cdate = 2019-09-29T00:00:00.000-0400
zdt = 2019-09-28 20:00:00.0

If this is for a time stamp for your SQL database: don't give your database a time stamp as a string. Give it a proper date-time object. Since JDBC 4.2 this means:

  • For an SQL timestamp with time zone (recommended for the vast majority of purposes) provide an OffsetDateTime ; many drivers accept an Instant too.
  • For an SQL timestamp without time zone provide a LocalDateTime .

So for example:

    java.sql.Date inputDate = getFromSomewhere();
    OffsetDateTime dateTimeForDatabase = inputDate.toLocalDate()
            .atStartOfDay(ZoneOffset.UTC)
            .toOffsetDateTime();
    System.out.println(dateTimeForDatabase);

    PreparedStatement stmt = yourDatabaseConnection.prepareStatement(
            "insert into your_table(your_timestamp_col) values (?)");
    stmt.setObject(1, dateTimeForDatabase);
    int rowsInserted = stmt.executeUpdate();

Example output from the print statement in the middle:

2019-09-29T00:00Z

The Z means UTC, so this is the same point in time as the 2019-09-28 20:00:00.0 you asked for, assuming that your JVM's time zone is some variant of North American Eastern Time (America/Toronto or America/New_York).

The object that you see in your debugger looks very much like a java.sql.Date object, so I have taken this type as my starting point. The java.sql.Date class is poorly designed, though, in fact a true hack on top of the already poorly designed java.util.Date class. It is also long outdated. So if you could get a modern type instead, for example a LocalDate , it would be advantageous.

What went wrong in your code?

A LocalDate is a date without time of day, for example 2019-09-29. You were trying to format one using the format pattern yyyy-MM-dd'T'HH:mm:ss.SSS'Z' . So you are asking to include the time of day in the result, but as I said, the LocalDate hasn't got a time of day, so this does not make sense. The error message that you got was actually pretty precise:

Unsupported field: HourOfDay

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